PostgresSQL提供了許多數(shù)據(jù)庫(kù)配置參數(shù),本章將介紹每個(gè)參數(shù)的作用和如何配置每一個(gè)參數(shù)。
創(chuàng)新互聯(lián)-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價(jià)比玉龍網(wǎng)站開(kāi)發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫(kù),直接使用。一站式玉龍網(wǎng)站制作公司更省心,省錢(qián),快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋玉龍地區(qū)。費(fèi)用合理售后完善,十載實(shí)體公司更值得信賴。
10.1 如何設(shè)置數(shù)據(jù)庫(kù)參數(shù)
所有的參數(shù)的名稱都是不區(qū)分大小寫(xiě)的。每個(gè)參數(shù)的取值是布爾型、整型、浮點(diǎn)型和字符串型這四種類型中的一個(gè),分別用boolean
、integer、 floating point和string表示。布爾型的值可以寫(xiě)成ON、OFF、 TRUE、 FALSE、 YES、 NO、 1和 0,而且不區(qū)分大小
寫(xiě)。
有些參數(shù)用來(lái)配置內(nèi)存大小和時(shí)間值。內(nèi)存大小的單位可以是KB、MB和GB。時(shí)間的單位可以是毫秒、秒、分鐘、小時(shí)和天。用ms表示
毫秒,用s表示秒,用 min表示分鐘,用h表示小時(shí),用d表示天。表示內(nèi)存大小和時(shí)間值的參數(shù)參數(shù)都有一個(gè)默認(rèn)的單位,如果用戶
在設(shè)置參數(shù)的值時(shí)沒(méi)有指定單位,則以參數(shù)默認(rèn)的 單位為準(zhǔn)。例如,參數(shù)shared_buffers表示數(shù)據(jù)緩沖區(qū)的大小,它的默認(rèn)單位是
數(shù)據(jù)塊的個(gè)數(shù),如果把它的值設(shè)成8,因?yàn)槊總€(gè)數(shù)據(jù)塊的大小是 8KB,則數(shù)據(jù)緩沖區(qū)的大小是8*8=64KB,如果將它的值設(shè)成128MB,
則數(shù)據(jù)緩沖區(qū)的大小是128MB。參數(shù)vacuum_cost_delay 的默認(rèn)單位是毫秒,如果把它的值設(shè)成10,則它的值是10毫秒,如果把它的
值設(shè)成100s,則它的值是100秒。
所有的參數(shù)都放在文件 postgresql.conf中,下面是一個(gè)文件實(shí)例:
#這是注釋
log_connections = yes
log_destination = 'syslog'
search_path = '"$user", public'
每一行只能指定一個(gè)參數(shù),空格和空白行都會(huì)被忽略?!?#”表示注釋,注釋信息不用單獨(dú)占一行,可以出現(xiàn)在配置文件的任何地方
。如果參數(shù)的值不是簡(jiǎn)單的標(biāo)識(shí)符和數(shù)字,應(yīng)該用單引號(hào)引起來(lái)。如果參數(shù)的值中有單引號(hào),應(yīng)該寫(xiě)兩個(gè)單引號(hào),或者在單引號(hào)前面
加一個(gè)反斜杠。
一個(gè)配置文件也可以包含其它配置文件,使用include指令能夠達(dá)到這個(gè)目的,例如,假設(shè)postgresql.conf文件中有下面一行:
include ‘my.confg’
文件my.config中的配置信息也會(huì)被數(shù)據(jù)庫(kù)讀入。include指令指定的配置文件也可以用include指令再包含其它配置文件。如果
include指令中指定的文件名不是絕對(duì)路徑,數(shù)據(jù)庫(kù)會(huì)在postgresql.conf文件所在的目錄下查找這個(gè)文件。
用戶也可以在數(shù)據(jù)庫(kù)啟動(dòng)以后修改postgresql.conf配置文件,使用命令pg_ctl reload來(lái)通知數(shù)據(jù)庫(kù)重新讀取配置文件。注意,有些
參數(shù)在數(shù)據(jù)庫(kù)啟動(dòng)以后,不能被修改,只有重新啟動(dòng)數(shù)據(jù)庫(kù)以后,新的參數(shù)值才能生效。另外一些參數(shù)可 以在數(shù)據(jù)庫(kù)運(yùn)行過(guò)程中被
修改而且新的值可以立即生效。所以數(shù)據(jù)庫(kù)在運(yùn)行過(guò)程中重新讀取參數(shù)配置文件以后,不是所有的參數(shù)都會(huì)被賦給新的值。
用戶可以在自己建立的會(huì)話中執(zhí)行命令SET修改某些配置參數(shù)的值(注意不是全部參數(shù)),例如:
SET ENABLE_SEQSCAN TO OFF;
另外,有些參數(shù)只有數(shù)據(jù)庫(kù)超級(jí)用戶才能使用SET命令修改它們。用戶可以在psql中執(zhí)行命令show來(lái)查看所有的數(shù)據(jù)庫(kù)參數(shù)的當(dāng)前值
。例如:
(1)show all; --查看所有數(shù)據(jù)庫(kù)參數(shù)的值
(2)show search_path; --查看參數(shù)search_path的值
10.2 連接與認(rèn)證
10.2.1 連接設(shè)置
listen_addresses (string)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它指定數(shù)據(jù)庫(kù)用來(lái)監(jiān)聽(tīng)客戶端連接的TCP/IP地址。默認(rèn)是值是* ,表示數(shù)據(jù)庫(kù)在啟動(dòng)以
后將在運(yùn)行數(shù)據(jù)的機(jī)器上的所有的IP地址上監(jiān)聽(tīng)用戶請(qǐng)求(如果機(jī)器只有一個(gè)網(wǎng)卡,只有一個(gè)IP地址,有多個(gè)網(wǎng)卡的機(jī)器有多個(gè) IP
地址)??梢詫?xiě)成機(jī)器的名字,也可以寫(xiě)成IP地址,不同的值用逗號(hào)分開(kāi),例如,’server01’, ’140.87.171.49, 140.87.171.21
’。如果被設(shè)成localhost,表示數(shù)據(jù)庫(kù)只能接受本地的客戶端連接請(qǐng)求,不能接受遠(yuǎn)程的客戶端連接請(qǐng)求。
port (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它指定數(shù)據(jù)庫(kù)監(jiān)聽(tīng)?wèi)舳诉B接的TCP端口。默認(rèn)值是5432。
max_connections (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它決定數(shù)據(jù)庫(kù)可以同時(shí)建立的最大的客戶端連接的數(shù)目。默認(rèn)值是100。
superuser_reserved_connections (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它表示預(yù)留給超級(jí)用戶的數(shù)據(jù)庫(kù)連接數(shù)目。它的值必須小于max_connections。 普通用
戶可以在數(shù)據(jù)庫(kù)中建立的最大的并發(fā)連接的數(shù)目是max_connections- superuser_reserved_connections, 默認(rèn)值是3。
unix_socket_group (string)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。設(shè)置Unix-domain socket所在的操作系統(tǒng)用戶組。默認(rèn)值是空串,用啟動(dòng)數(shù)據(jù)庫(kù)的操作
系統(tǒng)用戶所在的組作為Unix-domain socket的用戶組。
unix_socket_permissions (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它設(shè)置Unix-domain socket的訪問(wèn)權(quán)限,格式與操作系統(tǒng)的文件訪問(wèn)權(quán)限是一樣的。默
認(rèn)值是0770,表示任何操作系統(tǒng)用戶都能訪問(wèn)Unix-domain socket??梢栽O(shè)為0770(所有Unix-domain socket文件的所有者所在的組
包含的用戶都能訪問(wèn))和0700(只有Unix-domain socket文件的所有者才能訪問(wèn))。對(duì)于Unix-domain socket,只有寫(xiě)權(quán)限才有意義,
讀和執(zhí)行權(quán)限是沒(méi)有意義的。
tcp_keepalives_idle (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是0,意思是使用操作系統(tǒng)的默認(rèn)值。它設(shè)置TCP套接字的TCP_KEEPIDLE屬性。這個(gè)參數(shù)對(duì)于
通過(guò)Unix-domain socket建立的數(shù)據(jù)庫(kù)連接沒(méi)有任何影響。
tcp_keepalives_interval (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是0,意思是使用操作系統(tǒng)的默認(rèn)值。它設(shè)置TCP套接字的TCP_KEEPINTVL屬性。這個(gè)參數(shù)對(duì)
于通過(guò)Unix-domain socket建立的數(shù)據(jù)庫(kù)連接沒(méi)有任何影響。
tcp_keepalives_count (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是0,意思是使用操作系統(tǒng)的默認(rèn)值。它設(shè)置TCP套接字的TCP_KEEPCNT屬性。這個(gè)參數(shù)對(duì)于
通過(guò)Unix-domain socket建立的數(shù)據(jù)庫(kù)連接沒(méi)有任何影響。
10.2.2. 安全與認(rèn)證
authentication_timeout (integer)
這個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置,它指定一個(gè)時(shí)間長(zhǎng)度,在這個(gè)時(shí)間長(zhǎng)度內(nèi),必須完成客戶端認(rèn)證操作,否則客戶端
連接請(qǐng)求將被拒絕。它可以阻止某些客戶端進(jìn)行認(rèn)證時(shí)長(zhǎng)時(shí)間占用數(shù)據(jù)庫(kù)連接。單位是秒,默認(rèn)值是60。
ssl (boolean)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。決定數(shù)據(jù)庫(kù)是否接受SSL連接。默認(rèn)值是off。
ssl_ciphers (string)
指定可以使用的SSL加密算法。查看操作系統(tǒng)關(guān)于openssl的用戶手冊(cè)可以得到完整的加密算法列表(執(zhí)行命令openssl ciphers –v
也可以得到)。
10.3 資源消耗
10.3.1 內(nèi)存
shared_buffers (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它表示數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)塊的個(gè)數(shù),每個(gè)數(shù)據(jù)塊的大小是8KB。數(shù)據(jù)緩沖區(qū)位于數(shù)據(jù)
庫(kù)的共享內(nèi)存中,它越大越好,不能小于128KB。默認(rèn)值是1024。
temp_buffers (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是8MB。它決定存放臨時(shí)表的數(shù)據(jù)緩沖區(qū)中的數(shù)據(jù)塊的個(gè)數(shù),每個(gè)數(shù)據(jù)塊的大小是8KB。臨時(shí)
表緩沖區(qū)存放在每個(gè)數(shù)據(jù)庫(kù)進(jìn)程的私有內(nèi)存中,而不是存放在數(shù)據(jù)庫(kù)的共享內(nèi)存中。默認(rèn)值是1024。
max_prepared_transactions (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它決定能夠同時(shí)處于prepared狀態(tài)的事務(wù)的最大數(shù)目(參考PREPARE TRANSACTION命令
)。如果它的值被設(shè)為0。則將數(shù)據(jù)庫(kù)將關(guān)閉prepared事務(wù)的特性。它的值通常應(yīng)該和max_connections的值 一樣大。默認(rèn)值是5。
work_mem (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。它決定數(shù)據(jù)庫(kù)的排序操作和哈希表使用的內(nèi)存緩沖區(qū)的大小。如何work_mem指定的內(nèi)存被耗盡,數(shù)
據(jù)庫(kù)將使用磁盤(pán)文件進(jìn) 行完成操作,速度會(huì)慢很多。ORDER BY、DISTINCT和merge連接會(huì)使用排序操作。哈希表在Hash連接、hash聚
集函數(shù)和用哈希表來(lái)處理IN謂詞中的子查詢中被使用。單位是 KB,默認(rèn)值是1024。
maintenance_work_mem (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。它決定數(shù)據(jù)庫(kù)的維護(hù)操作使用的內(nèi)存空間的大小。數(shù)據(jù)庫(kù)的維護(hù)操作包括VACUUM、CREATE INDEX和
ALTER TABLE ADD FOREIGN KEY等操作。 maintenance_work_mem的值如果比較大,通常可以縮短VACUUM數(shù)據(jù)庫(kù)和從dump文件中恢復(fù)數(shù)
據(jù)庫(kù)需要的時(shí)間。 maintenance_work_mem存放在每個(gè)數(shù)據(jù)庫(kù)進(jìn)程的私有內(nèi)存中,而不是存放在數(shù)據(jù)庫(kù)的共享內(nèi)存中。單位是KB,默
認(rèn)值是16384。
max_stack_depth (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置,但只有數(shù)據(jù)庫(kù)超級(jí)用戶才能修改它。它決定一個(gè)數(shù)據(jù)庫(kù)進(jìn)程在運(yùn)行時(shí)的STACK所占的空間的最大值
。數(shù)據(jù)庫(kù)進(jìn)程在運(yùn)行時(shí),會(huì) 自動(dòng)檢查自己的STACK大小是否超過(guò)max_stack_depth,如果超過(guò),會(huì)自動(dòng)終止當(dāng)前事務(wù)。這個(gè)值應(yīng)該比
操作系統(tǒng)設(shè)置的進(jìn)程STACK的大小 的上限小1MB。使用操作系統(tǒng)命令“ulimit –s“可以得到操作系統(tǒng)設(shè)置的進(jìn)程STACK的最大值。單
位是KB,默認(rèn)值是100。
10.3.2 Free Space Map
數(shù)據(jù)庫(kù)的所有可用空間信息都存放在一個(gè)叫free space map (FSM)的結(jié)構(gòu)中,它記載數(shù)據(jù)文件中每個(gè)數(shù)據(jù)塊的可用空間的大小。FSM
中沒(méi)有記錄的數(shù)據(jù)塊,即使有可用空間,也不會(huì)系統(tǒng)使用。系統(tǒng)如果需要新的物理存 儲(chǔ)空間,會(huì)首先在FSM中查找,如果FSM中沒(méi)有
一個(gè)數(shù)據(jù)頁(yè)有足夠的可用空間,系統(tǒng)就會(huì)自動(dòng)擴(kuò)展數(shù)據(jù)文件。所以,F(xiàn)SM如果太小,會(huì)導(dǎo)致系統(tǒng)頻繁地?cái)U(kuò)展數(shù) 據(jù)文件,浪費(fèi)物理存儲(chǔ)
空間。命令VACUUM VERBOSE在執(zhí)行結(jié)束以后,會(huì)提示當(dāng)前的FSM設(shè)置是否滿足需要,如果FSM的參數(shù)值太小,它會(huì)提示增大參數(shù)。
FSM存放在數(shù)據(jù)庫(kù)的共享內(nèi)存中,由于物理內(nèi)存的限制,F(xiàn)SM不可能跟蹤數(shù)據(jù)庫(kù)的所有的數(shù)據(jù)文件的所有數(shù)據(jù)塊的可用空間信息,只能
跟蹤一部分?jǐn)?shù)據(jù)塊的可用空間信息。
max_fsm_relations (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。默認(rèn)值是1000。它決定FSM跟蹤的表和索引的個(gè)數(shù)的上限。每個(gè)表和索引在FSM中占7個(gè)
字節(jié)的存儲(chǔ)空間。
max_fsm_pages (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它決定FSM中跟蹤的數(shù)據(jù)塊的個(gè)數(shù)的上限。initdb在創(chuàng)建數(shù)據(jù)庫(kù)集群時(shí)會(huì)根據(jù)物理內(nèi)存
的大小決定它的值。每 個(gè)數(shù)據(jù)塊在fsm中占6個(gè)字節(jié)的存儲(chǔ)空間。它的大小不能小于16 * max_fsm_relations。默認(rèn)值是20000。
10.3.3 內(nèi)核資源
max_files_per_process (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。他設(shè)定每個(gè)數(shù)據(jù)庫(kù)進(jìn)程能夠打開(kāi)的文件的數(shù)目。默認(rèn)值是1000。
shared_preload_libraries (string)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。它設(shè)置數(shù)據(jù)庫(kù)在啟動(dòng)時(shí)要加載的操作系統(tǒng)共享庫(kù)文件。如果有多個(gè)庫(kù)文件,名字用逗號(hào)
分開(kāi)。如果數(shù)據(jù)庫(kù)在啟動(dòng)時(shí)未找到shared_preload_libraries指定的某個(gè)庫(kù)文件,數(shù)據(jù)庫(kù)將無(wú)法啟動(dòng)。默認(rèn)值為空串。
10.3.4 垃圾收集
執(zhí)行VACUUM 和ANALYZE命令時(shí),因?yàn)樗鼈儠?huì)消耗大量的CPU與IO資源,而且執(zhí)行一次要花很長(zhǎng)時(shí)間,這樣會(huì)干擾系統(tǒng)執(zhí)行應(yīng)用程序發(fā)
出的SQL命令。為了解決這個(gè) 問(wèn)題,VACUUM 和ANALYZE命令執(zhí)行一段時(shí)間后,系統(tǒng)會(huì)暫時(shí)終止它們的運(yùn)行,過(guò)一段時(shí)間后再繼續(xù)執(zhí)行
這兩個(gè)命令。這個(gè)特性在默認(rèn)的情況下是關(guān)閉的。將參數(shù) vacuum_cost_delay設(shè)為一個(gè)非零的正整數(shù)就可以打開(kāi)這個(gè)特性。
用戶通常只需要設(shè)置參數(shù)vacuum_cost_delay和vacuum_cost_limit,其它的參數(shù)使用默認(rèn)值即可。VACUUM 和ANALYZE命令在執(zhí)行過(guò)程
中,系統(tǒng)會(huì)計(jì)算它們執(zhí)行消耗的資源,資源的數(shù)量用一個(gè)正整數(shù)表示,如果資源的數(shù)量超過(guò) vacuum_cost_limit,則執(zhí)行命令的進(jìn)程
會(huì)進(jìn)入睡眠狀態(tài),睡眠的時(shí)間長(zhǎng)度是是vacuum_cost_delay。 vacuum_cost_limit的值越大,VACUUM 和ANALYZE命令在執(zhí)行的過(guò)程中
,睡眠的次數(shù)就越少,反之,vacuum_cost_limit的值越小,VACUUM 和ANALYZE命令在執(zhí)行的過(guò)程中,睡眠的次數(shù)就越多。
vacuum_cost_delay (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是0。它決定執(zhí)行VACUUM 和ANALYZE命令的進(jìn)程的睡眠時(shí)間。單位是微秒。它的值最好是10
的整數(shù),如果不是10的整數(shù),系統(tǒng)會(huì)自動(dòng)將它設(shè)為比該值大的并且最接近該值的是10 的倍數(shù)的整數(shù)。如果值是0,VACUUM 和ANALYZE
命令在執(zhí)行過(guò)程中不會(huì)主動(dòng)進(jìn)入睡眠狀態(tài),會(huì)一直執(zhí)行下去直到結(jié)束。
vacuum_cost_page_hit (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是1。
vacuum_cost_page_miss (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是10。
vacuum_cost_page_dirty (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是20。
vacuum_cost_limit (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。默認(rèn)值是200。
10.3.5 后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程
后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程負(fù)責(zé)將數(shù)據(jù)緩沖區(qū)中的被修改的數(shù)據(jù)塊(又叫臟數(shù)據(jù)塊)寫(xiě)回到數(shù)據(jù)庫(kù)物理文件中。
bgwriter_delay (integer)
這個(gè)參數(shù)只能在文件postgresql.conf中設(shè)置。它決定后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程的睡眠時(shí)間。后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程每次完成寫(xiě)數(shù)據(jù)到物理文件
中的任務(wù)以后, 就會(huì)睡眠bgwriter_delay指定的時(shí)間。 bgwriter_delay的值應(yīng)該是10的倍數(shù),如果用戶設(shè)定的值不是10的倍數(shù),數(shù)
據(jù)庫(kù)會(huì)自動(dòng)將參數(shù)的值設(shè)為比用戶指定的值大的最接近用戶指定的值 的同時(shí)是10的倍數(shù)的值。單位是毫秒,默認(rèn)值是200。
bgwriter_lru_maxpages (integer)
這個(gè)參數(shù)只能在文件postgresql.conf中設(shè)置。默認(rèn)值是100。后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程每次寫(xiě)臟數(shù)據(jù)塊時(shí),寫(xiě)到外部文件中的臟數(shù)據(jù)塊的個(gè)
數(shù)不能超過(guò) bgwriter_lru_maxpages指定的值。例如,如果它的值是500,則后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程每次寫(xiě)到物理文件的數(shù)據(jù)頁(yè)的個(gè)數(shù)不
能超過(guò)500,若 超過(guò),進(jìn)程將進(jìn)入睡眠狀態(tài),等下次醒來(lái)再執(zhí)行寫(xiě)物理文件的任務(wù)。如果它的值被設(shè)為0, 后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程將不會(huì)
寫(xiě)任何物理文件(但還會(huì)執(zhí)行檢查點(diǎn)操作)。
bgwriter_lru_multiplier (floating point)
這個(gè)參數(shù)只能在文件postgresql.conf中設(shè)置。默認(rèn)值是2.0。它決定后臺(tái)寫(xiě)數(shù)據(jù)庫(kù)進(jìn)程每次寫(xiě)物理文件時(shí),寫(xiě)到外部文件中的臟數(shù)據(jù)
塊的個(gè)數(shù) (不能超過(guò)bgwriter_lru_maxpages指定的值)。一般使用默認(rèn)值即可,不需要修改這個(gè)參數(shù)。這個(gè)參數(shù)的值越大,后臺(tái)寫(xiě)
數(shù)據(jù)庫(kù)進(jìn)程每次寫(xiě) 的臟數(shù)據(jù)塊的個(gè)數(shù)就越多。
10.4 事務(wù)日志
full_page_writes (boolean)
這個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置。默認(rèn)值是on。打開(kāi)這個(gè)參數(shù),可以提高數(shù)據(jù)庫(kù)的可靠性,減少數(shù)據(jù)丟失的概率,但
是會(huì)產(chǎn)生過(guò)多的事務(wù)日志,降低數(shù)據(jù)庫(kù)的性能。
wal_buffers (integer)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。默認(rèn)值是8。它指定事務(wù)日志緩沖區(qū)中包含的數(shù)據(jù)塊的個(gè)數(shù),每個(gè)數(shù)據(jù)塊的大小是8KB,
所以默認(rèn)的事務(wù)日志緩沖區(qū)的大小是8*8=64KB。事務(wù)日志緩沖區(qū)位于數(shù)據(jù)庫(kù)的共享內(nèi)存中。
wal_writer_delay (integer)
這個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置。它決定寫(xiě)事務(wù)日志進(jìn)程的睡眠時(shí)間。WAL進(jìn)程每次在完成寫(xiě)事務(wù)日志的任務(wù)后,就會(huì)
睡眠 wal_writer_delay指定的時(shí)間,然后醒來(lái),繼續(xù)將新產(chǎn)生的事務(wù)日志從緩沖區(qū)寫(xiě)到WAL文件中。單位是毫秒(millisecond),
默認(rèn) 值是200。
commit_delay (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。它設(shè)定事務(wù)在發(fā)出提交命令以后的睡眠時(shí)間,只有在睡眠了commit_delay指定的時(shí)間以后,事務(wù)產(chǎn)
生的事務(wù)日志才會(huì) 被寫(xiě)到事務(wù)日志文件中,事務(wù)才能真正地提交。增大這個(gè)參數(shù)會(huì)增加用戶的等待時(shí)間,但是可以讓多個(gè)事務(wù)被同
時(shí)提交,提高系統(tǒng)的性能。如果數(shù)據(jù)庫(kù)中的負(fù)載比較 高,而且大部分事務(wù)都是更新類型的事務(wù),可以考慮增大這個(gè)參數(shù)的值。下面
的參數(shù)commit_siblings會(huì)影響commit_delay是否生效。 默認(rèn)值是0,單位是微秒(microsecond)。
commit_siblings (integer)
這個(gè)參數(shù)可以在任何時(shí)候被設(shè)置。這個(gè)參數(shù)的值決定參數(shù)commit_delay是否生效。假設(shè)commit_siblings的值是5,如果一個(gè)事務(wù)發(fā)出
一個(gè)提交請(qǐng)求,此時(shí),如果數(shù)據(jù)庫(kù)中正在執(zhí)行的事務(wù)的個(gè)數(shù)大于或等于5,那么該事務(wù)將睡眠commit_delay指定的時(shí)間。如果數(shù)據(jù)庫(kù)
中正在執(zhí)行的事務(wù) 的個(gè)數(shù)小于5,這個(gè)事務(wù)將直接提交。默認(rèn)值是5。
10.5 檢查點(diǎn)
checkpoint_segments (integer)
這個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置。默認(rèn)值是3。它影響系統(tǒng)何時(shí)啟動(dòng)一個(gè)檢查點(diǎn)操作。如果上次檢查點(diǎn)操作結(jié)束以后,
系統(tǒng)產(chǎn)生的事 務(wù)日志文件的個(gè)數(shù)超過(guò)checkpoint_segments的值,系統(tǒng)就會(huì)自動(dòng)啟動(dòng)一個(gè)檢查點(diǎn)操作。增大這個(gè)參數(shù)會(huì)增加數(shù)據(jù)庫(kù)崩
潰以后恢復(fù)操作需要的時(shí) 間。
checkpoint_timeout (integer)
這個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置。單位是秒,默認(rèn)值是300。它影響系統(tǒng)何時(shí)啟動(dòng)一個(gè)檢查點(diǎn)操作。如果現(xiàn)在的時(shí)間減
去上次檢查 點(diǎn)操作結(jié)束的時(shí)間超過(guò)了checkpoint_timeout的值,系統(tǒng)就會(huì)自動(dòng)啟動(dòng)一個(gè)檢查點(diǎn)操作。增大這個(gè)參數(shù)會(huì)增加數(shù)據(jù)庫(kù)崩
潰以后恢復(fù)操作需要的時(shí) 間。
checkpoint_completion_target (floating point)
這個(gè)參數(shù)控制檢查點(diǎn)操作的執(zhí)行時(shí)間。合法的取值在0到1之間,默認(rèn)值是0.5。不要輕易地改變這個(gè)參數(shù)的值,使用默認(rèn)值即可。 這
個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置。
10.6 歸檔模式
archive_mode (boolean)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。默認(rèn)值是off。它決定數(shù)據(jù)庫(kù)是否打開(kāi)歸檔模式。
archive_dir (string)
這個(gè)參數(shù)只有在啟動(dòng)數(shù)據(jù)庫(kù)時(shí),才能被設(shè)置。默認(rèn)值是空串。它設(shè)定存放歸檔事務(wù)日志文件的目錄。
archive_timeout (integer)
這個(gè)參數(shù)只能在postgresql.conf文件中被設(shè)置。默認(rèn)值是0。單位是秒。如果archive_timeout的值不是0,而且當(dāng)前時(shí)間減去數(shù) 據(jù)
庫(kù)上次進(jìn)行事務(wù)日志文件切換的時(shí)間大于archive_timeout的值,數(shù)據(jù)庫(kù)將進(jìn)行一次事務(wù)日志文件切換。一般情況下,數(shù)據(jù)庫(kù)只有在
一個(gè)事務(wù)日志 文件寫(xiě)滿以后,才會(huì)切換到下一個(gè)事務(wù)日志文件,設(shè)定這個(gè)參數(shù)可以讓數(shù)據(jù)庫(kù)在一個(gè)事務(wù)日志文件尚未寫(xiě)滿的情況下
切換到下一個(gè)事務(wù)日志文件。
10.7 優(yōu)化器參數(shù)
10.7.1 存取方法參數(shù)
下列參數(shù)控制查詢優(yōu)化器是否使用特定的存取方法。除非對(duì)優(yōu)化器特別了解,一般情況下,使用它們默認(rèn)值即可。
enable_bitmapscan (boolean)
打開(kāi)或者關(guān)閉bitmap-scan 。默認(rèn)值是 on。
enable_hashagg (boolean)
打開(kāi)或者關(guān)閉hashed aggregation。默認(rèn)值是 on。
enable_hashjoin (boolean)
打開(kāi)或者關(guān)閉hash-join。默認(rèn)值是 on。
enable_indexscan (boolean)
打開(kāi)或者關(guān)閉index-scan。默認(rèn)值是 on。
enable_mergejoin (boolean)
打開(kāi)或者關(guān)閉merge-join。默認(rèn)值是 on。
enable_nestloop (boolean)
打開(kāi)或者關(guān)閉nested-loop join。默認(rèn)值是 on。不可能完全不使用nested-loop join,關(guān)閉這個(gè)參數(shù)會(huì)讓系統(tǒng)在有其它存取方法可
用的情況下,不使用nested-loop join。
enable_seqscan (boolean)
打開(kāi)或者關(guān)閉sequential scan。默認(rèn)值是 on。不可能完全不使用sequential scan,關(guān)閉這個(gè)參數(shù)會(huì)讓系統(tǒng)在有其它存取方法可用
的情況下,不使用sequential scan。
1、首先需要找到一個(gè)帶日期字段的數(shù)據(jù)表。
2、接下來(lái)向表中插入日期值。
3、然后通過(guò)month函數(shù)獲取月份即可,注意month里添加的是列名。
4、運(yùn)行SQL語(yǔ)句以后發(fā)現(xiàn)日期中的月份已經(jīng)被提取出來(lái)了。
5、另外還可以在Month中直接加GETDATE函數(shù)獲取當(dāng)前時(shí)間的月份。
表分區(qū)是解決一些因單表過(guò)大引用的性能問(wèn)題的方式,比如某張表過(guò)大就會(huì)造成查詢變慢,可能分區(qū)是一種解決方案。一般建議當(dāng)單表大小超過(guò)內(nèi)存就可以考慮表分區(qū)了。PostgreSQL的表分區(qū)有三種方式:
本文通過(guò)示例講解如何進(jìn)行這三種方式的分區(qū)。
為方便,我們通過(guò)Docker的方式啟動(dòng)一個(gè)PostgreSQL,可參考:《Docker啟動(dòng)PostgreSQL并推薦幾款連接工具》。我們要選擇較高的版本,否則不支持Hash分區(qū),命令如下:
先創(chuàng)建一張表帶有年齡,然后我們根據(jù)年齡分段來(lái)進(jìn)行分區(qū),創(chuàng)建表語(yǔ)句如下:
這個(gè)語(yǔ)句已經(jīng)指定了按age字段來(lái)分區(qū)了,接著創(chuàng)建分區(qū)表:
這里創(chuàng)建了四張分區(qū)表,分別對(duì)應(yīng)年齡是0到10歲、11到20歲、21到30歲、30歲以上。
接著我們插入一些數(shù)據(jù):
可以看到這里的表名還是 pkslow_person_r ,而不是具體的分區(qū)表,說(shuō)明對(duì)于客戶端是無(wú)感知的。
我們查詢也一樣的:
但實(shí)際上是有分區(qū)表存在的:
而且分區(qū)表與主表的字段是一致的。
查詢分區(qū)表,就只能查到那個(gè)特定分區(qū)的數(shù)據(jù)了:
類似的,列表分區(qū)是按特定的值來(lái)分區(qū),比較某個(gè)城市的數(shù)據(jù)放在一個(gè)分區(qū)里。這里不再給出每一步的講解,代碼如下:
當(dāng)我們查詢第一個(gè)分區(qū)的時(shí)候,只有廣州的數(shù)據(jù):
哈希分區(qū)是指按字段取哈希值后再分區(qū)。具體的語(yǔ)句如下:
可以看到創(chuàng)建分區(qū)表的時(shí)候,我們用了取模的方式,所以如果要?jiǎng)?chuàng)建N個(gè)分區(qū)表,就要取N取模。
隨便查詢一張分區(qū)表如下:
可以看到同是SZ的哈希值是一樣的,肯定會(huì)分在同一個(gè)分區(qū),而B(niǎo)J的哈希值取模后也屬于同一個(gè)分區(qū)。
本文講解了PostgreSQL分區(qū)的三種方式。
代碼請(qǐng)查看:
最近與同行 科技 交流,經(jīng)常被問(wèn)到分庫(kù)分表與分布式數(shù)據(jù)庫(kù)如何選擇,網(wǎng)上也有很多關(guān)于中間件+傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)(分庫(kù)分表)與NewSQL分布式數(shù)據(jù)庫(kù)的文章,但有些觀點(diǎn)與判斷是我覺(jué)得是偏激的,脫離環(huán)境去評(píng)價(jià)方案好壞其實(shí)有失公允。
本文通過(guò)對(duì)兩種模式關(guān)鍵特性實(shí)現(xiàn)原理對(duì)比,希望可以盡可能客觀、中立的闡明各自真實(shí)的優(yōu)缺點(diǎn)以及適用場(chǎng)景。
首先關(guān)于“中間件+關(guān)系數(shù)據(jù)庫(kù)分庫(kù)分表”算不算NewSQL分布式數(shù)據(jù)庫(kù)問(wèn)題,國(guó)外有篇論文pavlo-newsql-sigmodrec,如果根據(jù)該文中的分類,Spanner、TiDB、OB算是第一種新架構(gòu)型,Sharding-Sphere、Mycat、DRDS等中間件方案算是第二種(文中還有第三種云數(shù)據(jù)庫(kù),本文暫不詳細(xì)介紹)。
基于中間件(包括SDK和Proxy兩種形式)+傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)(分庫(kù)分表)模式是不是分布式架構(gòu)?我覺(jué)得是的,因?yàn)榇鎯?chǔ)確實(shí)也分布式了,也能實(shí)現(xiàn)橫向擴(kuò)展。但是不是"偽"分布式數(shù)據(jù)庫(kù)?從架構(gòu)先進(jìn)性來(lái)看,這么說(shuō)也有一定道理。"偽"主要體現(xiàn)在中間件層與底層DB重復(fù)的SQL解析與執(zhí)行計(jì)劃生成、存儲(chǔ)引擎基于B+Tree等,這在分布式數(shù)據(jù)庫(kù)架構(gòu)中實(shí)際上冗余低效的。為了避免引起真?zhèn)畏植际綌?shù)據(jù)庫(kù)的口水戰(zhàn),本文中NewSQL數(shù)據(jù)庫(kù)特指這種新架構(gòu)NewSQL數(shù)據(jù)庫(kù)。
NewSQL數(shù)據(jù)庫(kù)相比中間件+分庫(kù)分表的先進(jìn)在哪兒?畫(huà)一個(gè)簡(jiǎn)單的架構(gòu)對(duì)比圖:
這些大多也是NewSQL數(shù)據(jù)庫(kù)產(chǎn)品主要宣傳的點(diǎn),不過(guò)這些看起來(lái)很美好的功能是否真的如此?接下來(lái)針對(duì)以上幾點(diǎn)分別闡述下的我的理解。
這是把雙刃劍。
CAP限制
想想更早些出現(xiàn)的NoSQL數(shù)據(jù)庫(kù)為何不支持分布式事務(wù)(最新版的mongoDB等也開(kāi)始支持了),是缺乏理論與實(shí)踐支撐嗎?并不是,原因是CAP定理依然是分布式數(shù)據(jù)庫(kù)頭上的頸箍咒,在保證強(qiáng)一致的同時(shí)必然會(huì)犧牲可用性A或分區(qū)容忍性P。為什么大部分NoSQL不提供分布式事務(wù)?
那么NewSQL數(shù)據(jù)庫(kù)突破CAP定理限制了嗎?并沒(méi)有。NewSQL數(shù)據(jù)庫(kù)的鼻主Google Spanner(目前絕大部分分布式數(shù)據(jù)庫(kù)都是按照Spanner架構(gòu)設(shè)計(jì)的)提供了一致性和大于5個(gè)9的可用性,宣稱是一個(gè)“實(shí)際上是CA”的,其真正的含義是 系統(tǒng)處于 CA 狀態(tài)的概率非常高,由于網(wǎng)絡(luò)分區(qū)導(dǎo)致的服務(wù)停用的概率非常小 ,究其真正原因是其打造私有全球網(wǎng)保證了不會(huì)出現(xiàn)網(wǎng)絡(luò)中斷引發(fā)的網(wǎng)絡(luò)分區(qū),另外就是其高效的運(yùn)維隊(duì)伍,這也是cloud spanner的賣(mài)點(diǎn)。詳細(xì)可見(jiàn)CAP提出者Eric Brewer寫(xiě)的《Spanner, TrueTime 和CAP理論》。
完備性 :
兩階段提交協(xié)議是否嚴(yán)格支持ACID,各種異常場(chǎng)景是不是都可以覆蓋?
2PC在commit階段發(fā)送異常,其實(shí)跟最大努力一階段提交類似也會(huì)有部分可見(jiàn)問(wèn)題,嚴(yán)格講一段時(shí)間內(nèi)并不能保證A原子性和C一致性(待故障恢復(fù)后recovery機(jī)制可以保證最終的A和C)。完備的分布式事務(wù)支持并不是一件簡(jiǎn)單的事情,需要可以應(yīng)對(duì)網(wǎng)絡(luò)以及各種硬件包括網(wǎng)卡、磁盤(pán)、CPU、內(nèi)存、電源等各類異常,通過(guò)嚴(yán)格的測(cè)試。之前跟某友商交流,他們甚至說(shuō)目前已知的NewSQL在分布式事務(wù)支持上都是不完整的,他們都有案例跑不過(guò),圈內(nèi)人士這么篤定,也說(shuō)明了 分布式事務(wù)的支持完整程度其實(shí)是層次不齊的。
但分布式事務(wù)又是這些NewSQL數(shù)據(jù)庫(kù)的一個(gè)非常重要的底層機(jī)制,跨資源的DML、DDL等都依賴其實(shí)現(xiàn),如果這塊的性能、完備性打折扣,上層跨分片SQL執(zhí)行的正確性會(huì)受到很大影響。
性能
傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)也支持分布式事務(wù)XA,但為何很少有高并發(fā)場(chǎng)景下用呢? 因?yàn)閄A的基礎(chǔ)兩階段提交協(xié)議存在網(wǎng)絡(luò)開(kāi)銷大,阻塞時(shí)間長(zhǎng)、死鎖等問(wèn)題,這也導(dǎo)致了其實(shí)際上很少大規(guī)模用在基于傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)的OLTP系統(tǒng)中。
NewSQL數(shù)據(jù)庫(kù)的分布式事務(wù)實(shí)現(xiàn)也仍然多基于兩階段提交協(xié)議,例如google percolator分布式事務(wù)模型,
采用原子鐘+MVCC+ Snapshot Isolation(SI),這種方式通過(guò)TSO(Timestamp Oracle)保證了全局一致性,通過(guò)MVCC避免了鎖,另外通過(guò)primary lock和secondary lock將提交的一部分轉(zhuǎn)為異步,相比XA確實(shí)提高了分布式事務(wù)的性能。
但不管如何優(yōu)化,相比于1PC,2PC多出來(lái)的GID獲取、網(wǎng)絡(luò)開(kāi)銷、prepare日志持久化還是會(huì)帶來(lái)很大的性能損失,尤其是跨節(jié)點(diǎn)的數(shù)量比較多時(shí)會(huì)更加顯著,例如在銀行場(chǎng)景做個(gè)批量扣款,一個(gè)文件可能上W個(gè)賬戶,這樣的場(chǎng)景無(wú)論怎么做還是吞吐都不會(huì)很高。
雖然NewSQL分布式數(shù)據(jù)庫(kù)產(chǎn)品都宣傳完備支持分布式事務(wù),但這并不是說(shuō)應(yīng)用可以完全不用關(guān)心數(shù)據(jù)拆分,這些數(shù)據(jù)庫(kù)的最佳實(shí)踐中仍然會(huì)寫(xiě)到,應(yīng)用的大部分場(chǎng)景盡可能避免分布式事務(wù)。
既然強(qiáng)一致事務(wù)付出的性能代價(jià)太大,我們可以反思下是否真的需要這種強(qiáng)一致的分布式事務(wù)?尤其是在做微服務(wù)拆分后,很多系統(tǒng)也不太可能放在一個(gè)統(tǒng)一的數(shù)據(jù)庫(kù)中。嘗試將一致性要求弱化,便是柔性事務(wù),放棄ACID(Atomicity,Consistency, Isolation, Durability),轉(zhuǎn)投BASE(Basically Available,Soft state,Eventually consistent),例如Saga、TCC、可靠消息保證最終一致等模型,對(duì)于大規(guī)模高并發(fā)OLTP場(chǎng)景,我個(gè)人更建議使用柔性事務(wù)而非強(qiáng)一致的分布式事務(wù)。關(guān)于柔性事務(wù),筆者之前也寫(xiě)過(guò)一個(gè)技術(shù)組件,最近幾年也涌現(xiàn)出了一些新的模型與框架(例如阿里剛開(kāi)源的Fescar),限于篇幅不再贅述,有空再單獨(dú)寫(xiě)篇文章。
HA與異地多活
主從模式并不是最優(yōu)的方式,就算是半同步復(fù)制,在極端情況下(半同步轉(zhuǎn)異步)也存在丟數(shù)問(wèn)題,目前業(yè)界公認(rèn)更好的方案是基于paxos分布式一致性協(xié)議或者其它類paxos如raft方式,Google Spanner、TiDB、cockcoachDB、OB都采用了這種方式,基于Paxos協(xié)議的多副本存儲(chǔ),遵循過(guò)半寫(xiě)原則,支持自動(dòng)選主,解決了數(shù)據(jù)的高可靠,縮短了failover時(shí)間,提高了可用性,特別是減少了運(yùn)維的工作量,這種方案技術(shù)上已經(jīng)很成熟,也是NewSQL數(shù)據(jù)庫(kù)底層的標(biāo)配。
當(dāng)然這種方式其實(shí)也可以用在傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù),阿里、微信團(tuán)隊(duì)等也有將MySQL存儲(chǔ)改造支持paxos多副本的,MySQL也推出了官方版MySQL Group Cluster,預(yù)計(jì)不遠(yuǎn)的未來(lái)主從模式可能就成為 歷史 了。
需要注意的是很多NewSQL數(shù)據(jù)庫(kù)廠商宣傳基于paxos或raft協(xié)議可以實(shí)現(xiàn)【異地多活】,這個(gè)實(shí)際上是有前提的,那就是異地之間網(wǎng)絡(luò)延遲不能太高 。以銀行“兩地三中心”為例,異地之間多相隔數(shù)千里,延時(shí)達(dá)到數(shù)十毫秒,如果要多活,那便需異地副本也參與數(shù)據(jù)庫(kù)日志過(guò)半確認(rèn),這樣高的延時(shí)幾乎沒(méi)有OLTP系統(tǒng)可以接受的。
數(shù)據(jù)庫(kù)層面做異地多活是個(gè)美好的愿景,但距離導(dǎo)致的延時(shí)目前并沒(méi)有好的方案。 之前跟螞蟻團(tuán)隊(duì)交流,螞蟻異地多活的方案是在應(yīng)用層通過(guò)MQ同步雙寫(xiě)交易信息,異地DC將交易信息保存在分布式緩存中,一旦發(fā)生異地切換,數(shù)據(jù)庫(kù)同步中間件會(huì)告之?dāng)?shù)據(jù)延遲時(shí)間,應(yīng)用從緩存中讀取交易信息,將這段時(shí)間內(nèi)涉及到的業(yè)務(wù)對(duì)象例如用戶、賬戶進(jìn)行黑名單管理,等數(shù)據(jù)同步追上之后再將這些業(yè)務(wù)對(duì)象從黑名單中剔除。由于雙寫(xiě)的不是所有數(shù)據(jù)庫(kù)操作日志而只是交易信息,數(shù)據(jù)延遲只影響一段時(shí)間內(nèi)數(shù)據(jù),這是目前我覺(jué)得比較靠譜的異地度多活方案。
另外有些系統(tǒng)進(jìn)行了單元化改造,這在paxos選主時(shí)也要結(jié)合考慮進(jìn)去,這也是目前很多NewSQL數(shù)據(jù)庫(kù)欠缺的功能。
Scale橫向擴(kuò)展與分片機(jī)制
paxos算法解決了高可用、高可靠問(wèn)題,并沒(méi)有解決Scale橫向擴(kuò)展的問(wèn)題,所以分片是必須支持的。NewSQL數(shù)據(jù)庫(kù)都是天生內(nèi)置分片機(jī)制的,而且會(huì)根據(jù)每個(gè)分片的數(shù)據(jù)負(fù)載(磁盤(pán)使用率、寫(xiě)入速度等)自動(dòng)識(shí)別熱點(diǎn),然后進(jìn)行分片的分裂、數(shù)據(jù)遷移、合并,這些過(guò)程應(yīng)用是無(wú)感知的,這省去了DBA的很多運(yùn)維工作量。以TiDB為例,它將數(shù)據(jù)切成region,如果region到64M時(shí),數(shù)據(jù)自動(dòng)進(jìn)行遷移。
分庫(kù)分表模式下需要應(yīng)用設(shè)計(jì)之初就要明確各表的拆分鍵、拆分方式(range、取模、一致性哈?;蛘咦远x路由表)、路由規(guī)則、拆分庫(kù)表數(shù)量、擴(kuò)容方式等。相比NewSQL數(shù)據(jù)庫(kù),這種模式給應(yīng)用帶來(lái)了很大侵入和復(fù)雜度,這對(duì)大多數(shù)系統(tǒng)來(lái)說(shuō)也是一大挑戰(zhàn)。
這里有個(gè)問(wèn)題是NewSQL數(shù)據(jù)庫(kù)統(tǒng)一的內(nèi)置分片策略(例如tidb基于range)可能并不是最高效的,因?yàn)榕c領(lǐng)域模型中的劃分要素并不一致,這導(dǎo)致的后果是很多交易會(huì)產(chǎn)生分布式事務(wù)。 舉個(gè)例子,銀行核心業(yè)務(wù)系統(tǒng)是以客戶為維度,也就是說(shuō)客戶表、該客戶的賬戶表、流水表在絕大部分場(chǎng)景下是一起寫(xiě)的,但如果按照各表主鍵range進(jìn)行分片,這個(gè)交易并不能在一個(gè)分片上完成,這在高頻OLTP系統(tǒng)中會(huì)帶來(lái)性能問(wèn)題。
分布式SQL支持
常見(jiàn)的單分片SQL,這兩者都能很好支持。NewSQL數(shù)據(jù)庫(kù)由于定位與目標(biāo)是一個(gè)通用的數(shù)據(jù)庫(kù),所以支持的SQL會(huì)更完整,包括跨分片的join、聚合等復(fù)雜SQL。中間件模式多面向應(yīng)用需求設(shè)計(jì),不過(guò)大部分也支持帶拆分鍵SQL、庫(kù)表遍歷、單庫(kù)join、聚合、排序、分頁(yè)等。但對(duì)跨庫(kù)的join以及聚合支持就不夠了。
NewSQL數(shù)據(jù)庫(kù)一般并不支持存儲(chǔ)過(guò)程、視圖、外鍵等功能,而中間件模式底層就是傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù),這些功能如果只是涉及單庫(kù)是比較容易支持的。
NewSQL數(shù)據(jù)庫(kù)往往選擇兼容MySQL或者PostgreSQL協(xié)議,所以SQL支持僅局限于這兩種,中間件例如驅(qū)動(dòng)模式往往只需做簡(jiǎn)單的SQL解析、計(jì)算路由、SQL重寫(xiě),所以可以支持更多種類的數(shù)據(jù)庫(kù)SQL。
SQL支持的差異主要在于分布式SQL執(zhí)行計(jì)劃生成器,由于NewSQL數(shù)據(jù)庫(kù)具有底層數(shù)據(jù)的分布、統(tǒng)計(jì)信息,因此可以做CBO,生成的執(zhí)行計(jì)劃效率更高,而中間件模式下沒(méi)有這些信息,往往只能基于規(guī)則RBO(Rule-Based-Opimization),這也是為什么中間件模式一般并不支持跨庫(kù)join,因?yàn)閷?shí)現(xiàn)了效率也往往并不高,還不如交給應(yīng)用去做。
存儲(chǔ)引擎
傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)的存儲(chǔ)引擎設(shè)計(jì)都是面向磁盤(pán)的,大多都基于B+樹(shù)。B+樹(shù)通過(guò)降低樹(shù)的高度減少隨機(jī)讀、進(jìn)而減少磁盤(pán)尋道次數(shù),提高讀的性能,但大量的隨機(jī)寫(xiě)會(huì)導(dǎo)致樹(shù)的分裂,從而帶來(lái)隨機(jī)寫(xiě),導(dǎo)致寫(xiě)性能下降。NewSQL的底層存儲(chǔ)引擎則多采用LSM,相比B+樹(shù)LSM將對(duì)磁盤(pán)的隨機(jī)寫(xiě)變成順序?qū)?,大大提高了?xiě)的性能。不過(guò)LSM的的讀由于需要合并數(shù)據(jù)性能比B+樹(shù)差,一般來(lái)說(shuō)LSM更適合應(yīng)在寫(xiě)大于讀的場(chǎng)景。當(dāng)然這只是單純數(shù)據(jù)結(jié)構(gòu)角度的對(duì)比,在數(shù)據(jù)庫(kù)實(shí)際實(shí)現(xiàn)時(shí)還會(huì)通過(guò)SSD、緩沖、bloom filter等方式優(yōu)化讀寫(xiě)性能,所以讀性能基本不會(huì)下降太多。NewSQL數(shù)據(jù)由于多副本、分布式事務(wù)等開(kāi)銷,相比單機(jī)關(guān)系數(shù)據(jù)庫(kù)SQL的響應(yīng)時(shí)間并不占優(yōu),但由于集群的彈性擴(kuò)展,整體QPS提升還是很明顯的,這也是NewSQL數(shù)據(jù)庫(kù)廠商說(shuō)分布式數(shù)據(jù)庫(kù)更看重的是吞吐,而不是單筆SQL響應(yīng)時(shí)間的原因。
成熟度與生態(tài)
分布式數(shù)據(jù)庫(kù)是個(gè)新型通用底層軟件,準(zhǔn)確的衡量與評(píng)價(jià)需要一個(gè)多維度的測(cè)試模型,需包括發(fā)展現(xiàn)狀、使用情況、社區(qū)生態(tài)、監(jiān)控運(yùn)維、周邊配套工具、功能滿足度、DBA人才、SQL兼容性、性能測(cè)試、高可用測(cè)試、在線擴(kuò)容、分布式事務(wù)、隔離級(jí)別、在線DDL等等,雖然NewSQL數(shù)據(jù)庫(kù)發(fā)展經(jīng)過(guò)了一定時(shí)間檢驗(yàn),但多集中在互聯(lián)網(wǎng)以及傳統(tǒng)企業(yè)非核心交易系統(tǒng)中,目前還處于快速迭代、規(guī)模使用不斷優(yōu)化完善的階段。
相比而言,傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)則經(jīng)過(guò)了多年的發(fā)展,通過(guò)完整的評(píng)測(cè),在成熟度、功能、性能、周邊生態(tài)、風(fēng)險(xiǎn)把控、相關(guān)人才積累等多方面都具有明顯優(yōu)勢(shì),同時(shí)對(duì)已建系統(tǒng)的兼容性也更好。
對(duì)于互聯(lián)網(wǎng)公司,數(shù)據(jù)量的增長(zhǎng)壓力以及追求新技術(shù)的基因會(huì)更傾向于嘗試NewSQL數(shù)據(jù)庫(kù),不用再考慮庫(kù)表拆分、應(yīng)用改造、擴(kuò)容、事務(wù)一致性等問(wèn)題怎么看都是非常吸引人的方案。
對(duì)于傳統(tǒng)企業(yè)例如銀行這種風(fēng)險(xiǎn)意識(shí)較高的行業(yè)來(lái)說(shuō),NewSQL數(shù)據(jù)庫(kù)則可能在未來(lái)一段時(shí)間內(nèi)仍處于 探索 、審慎試點(diǎn)的階段?;谥虚g件+分庫(kù)分表模式架構(gòu)簡(jiǎn)單,技術(shù)門(mén)檻更低,雖然沒(méi)有NewSQL數(shù)據(jù)庫(kù)功能全面,但大部分場(chǎng)景最核心的訴求也就是拆分后SQL的正確路由,而此功能中間件模式應(yīng)對(duì)還是綽綽有余的,可以說(shuō)在大多數(shù)OLTP場(chǎng)景是夠用的。
限于篇幅,其它特性例如在線DDL、數(shù)據(jù)遷移、運(yùn)維工具等特性就不在本文展開(kāi)對(duì)比。
總結(jié)
如果看完以上內(nèi)容,您還不知道選哪種模式,那么結(jié)合以下幾個(gè)問(wèn)題,先思考下NewSQL數(shù)據(jù)庫(kù)解決的點(diǎn)對(duì)于自身是不是真正的痛點(diǎn):
如果以上有2到3個(gè)是肯定的,那么你可以考慮用NewSQL數(shù)據(jù)庫(kù)了,雖然前期可能需要一定的學(xué)習(xí)成本,但它是數(shù)據(jù)庫(kù)的發(fā)展方向,未來(lái)收益也會(huì)更高,尤其是互聯(lián)網(wǎng)行業(yè),隨著數(shù)據(jù)量的突飛猛進(jìn),分庫(kù)分表帶來(lái)的痛苦會(huì)與日俱增。當(dāng)然選擇NewSQL數(shù)據(jù)庫(kù)你也要做好承擔(dān)一定風(fēng)險(xiǎn)的準(zhǔn)備。
如果你還未做出抉擇,不妨再想想下面幾個(gè)問(wèn)題:
如果這些問(wèn)題有多數(shù)是肯定的,那還是分庫(kù)分表吧。在軟件領(lǐng)域很少有完美的解決方案,NewSQL數(shù)據(jù)庫(kù)也不是數(shù)據(jù)分布式架構(gòu)的銀彈。相比而言分庫(kù)分表是一個(gè)代價(jià)更低、風(fēng)險(xiǎn)更小的方案,它最大程度復(fù)用傳統(tǒng)關(guān)系數(shù)據(jù)庫(kù)生態(tài),通過(guò)中間件也可以滿足分庫(kù)分表后的絕大多數(shù)功能,定制化能力更強(qiáng)。 在當(dāng)前NewSQL數(shù)據(jù)庫(kù)還未完全成熟的階段,分庫(kù)分表可以說(shuō)是一個(gè)上限低但下限高的方案,尤其傳統(tǒng)行業(yè)的核心系統(tǒng),如果你仍然打算把數(shù)據(jù)庫(kù)當(dāng)做一個(gè)黑盒產(chǎn)品來(lái)用,踏踏實(shí)實(shí)用好分庫(kù)分表會(huì)被認(rèn)為是個(gè)穩(wěn)妥的選擇。
很多時(shí)候軟件選型取決于領(lǐng)域特征以及架構(gòu)師風(fēng)格,限于筆者知識(shí)與所屬行業(yè)特點(diǎn)所限,以上僅為個(gè)人粗淺的一些觀點(diǎn),歡迎討論。
網(wǎng)站名稱:postgresql取模的簡(jiǎn)單介紹
URL分享:http://m.rwnh.cn/article46/dscoseg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供App開(kāi)發(fā)、網(wǎng)頁(yè)設(shè)計(jì)公司、網(wǎng)站改版、ChatGPT、云服務(wù)器、小程序開(kāi)發(fā)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)