ProxySQL(4):多層配置系統
文章轉載自:https://www.cnblogs.com/f-ck-need-u/p/9280793.html
ProxySQL中的庫
使用ProxySQL的Admin管理介面連上ProxySQL,可檢視ProxySQL擁有的庫。
mysql -uadmin -padmin -h127.0.0.1 -P6032 --prompt 'admin> ' admin> show databases; +-----+---------------+-------------------------------------+ | seq | name | file | +-----+---------------+-------------------------------------+ | 0 | main | | | 2 | disk | /var/lib/proxysql/proxysql.db | | 3 | stats | | | 4 | monitor | | | 5 | stats_history | /var/lib/proxysql/proxysql_stats.db | +-----+---------------+-------------------------------------+
其中:
- main庫是ProxySQL最主要的庫,是需要修改配置時使用的庫,它其實是一個記憶體資料庫系統。所以,修改main庫中的配置後,必須將其持久化到disk上才能永久儲存。
- disk庫是磁碟資料庫,該資料庫結構和記憶體資料庫完全一致。當持久化記憶體資料庫中的配置時,其實就是寫入到disk庫中。磁碟資料庫的預設路徑為$DATADIR/proxysql.db。
- stats庫是統計資訊庫。這個庫中的資料一般是在檢索其內資料時臨時填充的,它儲存在記憶體中。因為沒有相關的配置項,所以無需持久化。
- monitor庫是監控後端MySQL節點相關的庫,該庫中只有幾個log類的表,監控模組收集到的監控資訊全都存放到對應的log表中。
- stats_history庫是1.4.4版新增的庫,用於存放歷史統計資料。預設路徑為
$DATADIR/proxysql_stats.db
。
ProxySQL內部使用的是SQLite3資料庫,無論是記憶體資料庫還是磁碟資料庫,都是通過SQLite3引擎進行解析、操作的。它和MySQL的語法可能稍有不同,但ProxySQL會對不相容的語法自動進行調整,最大程度上保證MySQL語句的有效率。
上面描述main庫的時候,只是說了記憶體資料庫需要持久化到disk庫才能永久儲存配置。但實際上,修改了main庫中的配置後,並不會立即生效,它還需要load到runtime的資料結構中才生效,只有在runtime資料結構中的配置才是對ProxySQL當前有效的配置。
ProxySQL的多層配置系統
ProxySQL的配置系統非常強大,它能線上修改幾乎所有配置(僅有的兩個需要重啟才能生效的變數為mysql-threads和mysql-stacksize),並在線生效、持久化儲存。這得益於它採用的多層配置系統。
多層配置系統結構如下:
+-------------------------+
| RUNTIME |
+-------------------------+
/|\ |
| |
[1] | [2] |
| \|/
+-------------------------+
| MEMORY |
+-------------------------+ _
/|\ | |\
| | \
[3] | [4] | \ [5]
| \|/ \
+-------------------------+ +---------------+
| DISK | | CONFIG FILE |
+-------------------------+ +---------------+
解釋下這個3層的配置系統。
最底層的是disk庫和config file。這裡需要注意,這裡的config file就是傳統的配置檔案,預設為/etc/proxysql.cnf,ProxySQL啟動時,主要是從disk庫中讀取配置載入到記憶體並最終載入到runtime生效,只有極少的幾個特定配置內容是從config file中載入的,除非是第一次初始化ProxySQL執行環境(或者disk庫為空)。
中間層的是memory,表示的是記憶體資料庫,其實就是main庫。通過管理介面修改的所有配置,都儲存在記憶體資料庫(main)中。當ProxySQL重啟或者崩潰時,這個記憶體資料庫中的資料會丟失,所以需要save到disk庫中。
最上層的是runtime,它是ProxySQL有關執行緒執行時讀取的資料結構。換句話說,該資料結構中的配置都是已生效的配置。所以,修改了main庫中的配置後,必須load到runtime資料結構中才能使其生效。
在上面的多層配置系統圖中,標註了[1]、[2]、[3]、[4]、[5]的序號。每個序號都有兩個操作方向from/to b,其實只是所站角度不同而已。以下是各序號對應的操作:
[1] :將記憶體資料庫中的配置載入到RUNTIME資料結構中
LOAD XXX FROM MEMORY
LOAD XXX TO RUNTIME
[2] :將RUNTIME資料結構中的配置持久化到記憶體資料庫中
SAVE XXX FROM RUNTIME
SAVE XXX TO MEMORY
[3] :將磁碟資料庫中的配置載入到記憶體資料庫中
LOAD XXX FROM DISK
LOAD XXX TO MEMORY
[4] :將記憶體資料庫中的配置持久化到磁碟資料庫中
SAVE XXX FROM MEMORY
SAVE XXX TO DISK
[5] :從傳統配置檔案中讀取配置載入到記憶體資料庫中
LOAD XXX FROM CONFIG
DISK/MEMORY/RUNTIME/CONFIG可以縮寫,只要能識別即可。例如MEMORY可以縮寫為MEM,runtime可以縮寫為run。
另外,上面的XXX是什麼?這表示要載入/儲存的是哪類配置。目前的ProxySQL支援以下幾種:
這些從main庫或disk庫中就可以檢視到。
admin> show tables from disk;
+------------------------------------+
| tables |
+------------------------------------+
| global_variables | # (1)
| mysql_collations | # (N)
| mysql_group_replication_hostgroups | # (2)
| mysql_query_rules | # (3)
| mysql_query_rules_fast_routing | # (4)
| mysql_replication_hostgroups | # (5)
| mysql_servers | # (6)
| mysql_users | # (7)
| proxysql_servers | # (8)
| scheduler | # (9)
+------------------------------------+
其中:
- (1)中包含兩類變數,以amdin-開頭的表示admin variables,以mysql-開頭的表示mysql variables。修改哪類變數,前文的XXX就代表哪類。
- (2,5,6)對應的都是mysql servers。
- (3,4)對應的是mysql query rules。
- (7)對應的mysql users。
- (9)對應的scheduler。
- (N)只是一張表,儲存的是ProxySQL支援的字符集和排序規則,它是不用修改的。
- (8)是ProxySQL的叢集配置表,該功能目前還處於實驗階段。如果想要配置該功能,則load/save proxysql_servers to/from ...。
以下是幾個示例:注意,幾乎所有配置都是在admin管理介面上修改的,這也是建議的配置方式。
(1).向ProxySQL的mysql_servers表中添加了一個後端節點。
load mysql servers to runtime; # 載入到runtime使該節點的配置生效
save mysql servers to disk; # 將該節點的配置持久化到磁碟資料庫中
上面兩句和下面兩句是等價的,只是操作方向不同(還使用了縮寫):
load mysql servers from mem;
save mysql servers from mem;
(2).向ProxySQL的mysql_users表中添加了用於傳送、處理SQL語句的使用者。
load mysql users to runtime;
save mysql users to disk;
(3).修改了以admin-開頭的變數。
load admin variables to runtime;
save admin variables to disk;
啟動ProxySQL時如何載入配置
如果ProxySQL是剛安裝的,或者磁碟資料庫檔案為空(甚至不存在),或者啟動ProxySQL時使用了選項--initial
,這幾種情況啟動ProxySQL時,都會從傳統配置檔案config file中讀取配置載入到記憶體資料庫,並自動load到runtime資料結構、save到磁碟資料庫,這是初始化ProxySQL執行環境的過程。
如果不是第一次啟動ProxySQL,由於已經存在磁碟資料庫檔案,這時ProxySQL會從磁碟資料庫中讀取幾乎所有的配置(即使傳統配置檔案中配置了某項,也不會去解析),但有3項是必須從傳統配置檔案中讀取的。這3項是:
- datadir:ProxySQL啟動時,必須從配置檔案中確定它的資料目錄,因為磁碟資料庫檔案、日誌以及其它一些檔案是存放在資料目錄下的。如果使用/etc/init.d/proxysql管理ProxySQL,則除了修改/etc/proxysql.cnf的datadir,還需要修改該指令碼中的datadir。
- restart_on_missing_heartbeats:MySQL執行緒丟失多少次心跳,就會殺掉這個執行緒並重啟它。預設值為10。
- execute_on_exit_failure:如果設定了該變數,ProxySQL父程序將在每次ProxySQL崩潰的時候執行已經定義好的指令碼。建議使用它來生成一些崩潰時的警告和日誌。注意,ProxySQL的重啟速度可能只有幾毫秒,因此很多其它的監控工具可能無法探測到ProxySQL的一次普通故障,此時可使用該變數。
關於傳統配置檔案
傳統配置檔案預設路徑為/etc/proxysql.cnf,也可以在二進位制程式proxysql上使用-c或--config
來手動指定配置檔案。
ProxySQL的傳統配置檔案示例如下:瀏覽下即可,幾乎不需要手動去配置proxysql.cnf。
datadir="/var/lib/proxysql"
admin_variables=
{
admin_credentials="admin:admin"
# mysql_ifaces="127.0.0.1:6032;/tmp/proxysql_admin.sock"
mysql_ifaces="0.0.0.0:6032"
# refresh_interval=2000
# debug=true
}
mysql_variables=
{
threads=4
max_connections=2048
default_query_delay=0
default_query_timeout=36000000
have_compress=true
poll_timeout=2000
# interfaces="0.0.0.0:6033;/tmp/proxysql.sock"
interfaces="0.0.0.0:6033"
default_schema="information_schema"
stacksize=1048576
server_version="5.5.30"
connect_timeout_server=3000
# make sure to configure monitor username and password
monitor_username="monitor"
monitor_password="monitor"
monitor_history=600000
monitor_connect_interval=60000
monitor_ping_interval=10000
monitor_read_only_interval=1500
monitor_read_only_timeout=500
ping_interval_server_msec=120000
ping_timeout_server=500
commands_stats=true
sessions_sort=true
connect_retries_on_failure=10
}
# defines all the MySQL servers
mysql_servers =
(
# {
# address = "127.0.0.1" # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
# port = 3306 # no default, required . If port is 0 , address is interpred as a Unix Socket Domain
# hostgroup = 0 # no default, required
# status = "ONLINE" # default: ONLINE
# weight = 1 # default: 1
# compression = 0 # default: 0
# max_replication_lag = 10 # default 0 . If greater than 0 and replication lag passes such threshold, the server is shunned
# },
# {
# address = "/var/lib/mysql/mysql.sock"
# port = 0
# hostgroup = 0
# },
# {
# address="127.0.0.1"
# port=21891
# hostgroup=0
# max_connections=200
# },
# { address="127.0.0.2" , port=3306 , hostgroup=0, max_connections=5 },
# { address="127.0.0.1" , port=21892 , hostgroup=1 },
# { address="127.0.0.1" , port=21893 , hostgroup=1 }
# { address="127.0.0.2" , port=3306 , hostgroup=1 },
# { address="127.0.0.3" , port=3306 , hostgroup=1 },
# { address="127.0.0.4" , port=3306 , hostgroup=1 },
# { address="/var/lib/mysql/mysql.sock" , port=0 , hostgroup=1 }
)
# defines all the MySQL users
mysql_users:
(
# {
# username = "username" # no default , required
# password = "password" # default: ''
# default_hostgroup = 0 # default: 0
# active = 1 # default: 1
# },
# {
# username = "root"
# password = ""
# default_hostgroup = 0
# max_connections=1000
# default_schema="test"
# active = 1
# },
# { username = "user1" , password = "password" , default_hostgroup = 0 , active = 0 }
)
#defines MySQL Query Rules
mysql_query_rules:
(
# {
# rule_id=1
# active=1
# match_pattern="^SELECT .* FOR UPDATE$"
# destination_hostgroup=0
# apply=1
# },
# {
# rule_id=2
# active=1
# match_pattern="^SELECT"
# destination_hostgroup=1
# apply=1
# }
)
scheduler=
(
# {
# id=1
# active=0
# interval_ms=10000
# filename="/var/lib/proxysql/proxysql_galera_checker.sh"
# arg1="0"
# arg2="0"
# arg3="0"
# arg4="1"
# arg5="/var/lib/proxysql/proxysql_galera_checker.log"
# }
)
mysql_replication_hostgroups=
(
# {
# writer_hostgroup=30
# reader_hostgroup=40
# comment="test repl 1"
# },
# {
# writer_hostgroup=50
# reader_hostgroup=60
# comment="test repl 2"
# }
)