自增ID,是資料庫中一個重要的功能,在Oracle和postgresql資料庫中,自增ID主要都是通過 序列實作的。
Greenplum資料庫,是基于postgresql實作的MPP資料庫叢集,其中也可以基于序列 實作自增ID的功能。
但在在近段時間使用時,就遇到一個錯誤:
建立一個包含自增ID的表,建表sql如下:
CREATE TABLE customers ( customerid SERIAL primary key , companyname character varying, contactname character varying, phone character varying, country character varying ) ;
執行insert操作,insert的sql如下:
insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1');
結果在執行過程中,遇到一個問題:
testDB=# testDB=# CREATE TABLE customers testDB-# ( testDB(# customerid SERIAL primary key , testDB(# companyname character varying, testDB(# contactname character varying, testDB(# phone character varying, testDB(# country character varying testDB(# ) ; NOTICE: CREATE TABLE will create implicit sequence "customers_customerid_seq" for serial column "customers.customerid" NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "customers_pkey" for table "customers" CREATE TABLE testDB=# testDB=# testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); ERROR: Interconnect Error: Could not connect to seqserver (connection: 11, host: 127.0.0.1, port: 51380). (seg0 slice1 tk-dat-asa201:40000 pid=29853) DETAIL: Connection refused (connect errno 111) testDB=#
這個問題非常奇怪,在Greenplum叢集中,建立和查詢序列沒有問題,但在插入時就會報錯。
而且提示的錯誤是,不能連接配接到序列伺服器, 但實際上通過下面的指令,是可以連接配接到序列伺服器的segment節點:
PGOPTIONS='-c gp_session_role=utility' psql -p 40000
在這種連接配接方式下,執行任何序列的添删改查操作,都是沒有問題的。
自己找了一段時間原因後,和别人溝通,确定原因根據報錯提示,應該還是網絡解析的問題,于是在各個節點上,依次進行自己主機和其他主機的ping指令,确認IP是多少。
connection: 11, host: 127.0.0.1, port: 51380
這個說明是 叢集中兩個主機之間網絡不通的問題;根據提示,直接懷疑是網絡DNS解析問題,造成通路拒絕。
資料庫之間連通,不應該是通過 127.0.0.1 位址的;
但在自己的主機上ping時,發現IP是這樣的:
所有将 /etc/hosts 中的這個IP注釋關閉:[[email protected] ~]# ping mc-data-asa211 PING mc-data-asa211 (127.0.0.1) 56(84) bytes of data. 64 bytes from localhost (127.0.0.1): icmp_seq=1 ttl=64 time=0.077 ms 64 bytes from localhost (127.0.0.1): icmp_seq=2 ttl=64 time=0.043 ms 64 bytes from localhost (127.0.0.1): icmp_seq=3 ttl=64 time=0.037 ms 64 bytes from localhost (127.0.0.1): icmp_seq=4 ttl=64 time=0.037 ms 64 bytes from localhost (127.0.0.1): icmp_seq=5 ttl=64 time=0.037 ms
修改之後,ping本機的IP位址:vim /etc/hosts [[email protected] ~]# vim /etc/hosts 127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 #127.0.0.1 mc-data-asa211 ## 注釋掉,不然有的情況下,會導緻Greenplum報錯 192.168.3.201 mc-data-asa211
這樣再執行序列插入操作,就沒有任何問題了:[[email protected] ~]# ping mc-data-asa211 PING mc-data-asa211 (192.168.3.201) 56(84) bytes of data. 64 bytes from mc-data-asa211 (192.168.3.201): icmp_seq=1 ttl=64 time=0.054 ms 64 bytes from mc-data-asa211 (192.168.3.201): icmp_seq=2 ttl=64 time=0.036 ms
通過這個問題發現,Greenplum叢集,有很多内部網絡通信,對于 /etc/hosts , iptables 等網絡配置一定要非常謹慎,不要有多餘資訊,否則會有各種奇怪問題。testDB=# select * from customers; customerid | companyname | contactname | phone | country ------------+-------------+-------------+-------+--------- (0 rows) testDB=# testDB=# testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# insert into customers(companyname,contactname,phone,country) values('a1','b1','c1','d1'); INSERT 0 1 testDB=# testDB=# select * from customers; customerid | companyname | contactname | phone | country ------------+-------------+-------------+-------+--------- 6 | a1 | b1 | c1 | d1 4 | a1 | b1 | c1 | d1 5 | a1 | b1 | c1 | d1 7 | a1 | b1 | c1 | d1 3 | a1 | b1 | c1 | d1 1 | a1 | b1 | c1 | d1 2 | a1 | b1 | c1 | d1 (7 rows)