昨天晚上在羣中和一些網友聊到了MySQL多實例的話題,最早接觸MySQL多實例還是在1年前,那會我剛步入運維行業,做過MySQL多實例的相關實驗,在後來的工作中也很少用到多實例,一直就淡漠了它,昨天再次提及,故此再次重新整理下以前的筆記,參考一些大牛的觀點,也參考我的好友賀總(尊稱)的意見,特此寫下這篇文章!廢話不說,切入正題....
在同一臺物理服務器上部署多個實例,而多實例的部署方式簡單,但是如何才能減少我們生產環境的維護成本,如何減少我們出錯的機會,如何方便我們後續的遷移和清理等工作,以及如何藉助多實例綁定的方式提高服務器的CPU資源利用率.
什麼情況下我們會考慮一臺物理服務器上部署多個實例,大致有以下幾種情況:
u採用了數據僞分佈式架構的原因,而項目啓動初期又不一定有那多的用戶量,爲此先一組物理數據庫服務器,但部署多個實例,方便後續遷移;
u爲規避mysql對SMP架構不支持的缺陷,使用多實例綁定處理器的辦法(NUMA處理器必須支持,不過現在大部分處理器都支持的!),把不同的數據庫分配到不同的實例上提供數據服務;
u一臺物理數據庫服務器支撐多個數據庫的數據服務,爲提高mysql複製的從機的恢復效率,採用多實例部署;
u已經爲雙主複製的mysql數據庫服務器架構,想部分重要業務的數據多一份異地機房的熱備份,而mysql複製暫不支持多主的複製模式,且不給用戶提供服務,爲有效控制成本,會考慮異地機房部署一臺性能超好的物理服務器,甚至外加磁盤櫃的方式,爲此也會部署多實例;
u傳統遊戲行業的MMO/MMORPG,以及Web Game,每一個服都對應一個數據庫,而可能要做很多數據查詢和數據訂正的工作,爲減少維護而出錯的概率,也可能採用多實例部署的方式,按區的概念分配數據庫;
下面是具體的搭建細節!
首先說明下MySQL的運行平臺:
CentOS 5.8 x86_64
MySQL-5.5.25
準備的軟件列表:
mysql-5.5.25.tar.gz
cmake-2.8.4.tar.gz
libunwind-1.0.1.tar.gz
gperftools-2.0.tar.gz
1. 安裝Tcmalloc 優化加速mysql
64位操作系統要先安裝libunwind庫,32位操作系統可以不要安裝:
cd /home/qiuzhijun/soft
tar zxf libunwind-1.0.1.tar.gz
cd libunwind-1.0.1
./configure
make;make install
cd ..
tar zxf gperftools-2.0.tar.gz
cd gperftools-2.0
./configure
make;make install
cd ..
echo "/usr/local/lib" > /etc/ld.so.conf.d/usr_local_lib.conf
/sbin/ldconfig
cd ..
利用TCMalloc提高mysql在高併發下的性能:
[root@MySQL5_10 ~]# ll /usr/local/lib/libtcmalloc.so
lrwxrwxrwx 1 root root 20 Jul 9 21:17 /usr/local/lib/libtcmalloc.so -> libtcmalloc.so.4.1.0
sed -i '/# executing mysqld_safe/a\export LD_PRELOAD=/usr/local/lib/libtcmalloc.so' /usr/local/webserver/mysql/bin/mysqld_safe
2.安裝mysql
useradd -s /sbin/nologin -M mysql
mkdir -p /data/mysql/data330{6,7}/{sock,data,tmpdir,log,binlog, innodb_log, innodb_ts}
chown -R mysql:mysql /data/mysql
cd /home/qiuzhijun/soft
tar zxf cmake-2.8.4.tar.gz
cd cmake-2.8.4
./bootstrap
gmake
gmake install
cd ..
tar zxvf mysql-5.5.25.tar.gz
cd mysql-5.5.25/
rm -rf CMakeCache.txt
cmake -DCMAKE_INSTALL_PREFIX=/usr/local/webserver/mysql -DMYSQL_UNIX_ADDR=/tmp/mysql.sock -DDEFAULT_CHARSET=utf8 -DDEFAULT_COLLATION=utf8_general_ci -DEXTRA_CHARSETS=all -DWITH_MYISAM_STORAGE_ENGINE=1 -DWITH_INNOBASE_STORAGE_ENGINE=1 -DWITH_READLINE=1 -DENABLED_LOCAL_INFILE=1 -DMYSQL_DATADIR=/data/mysql/data -DMYSQL_TCP_PORT=3306 -DWITH_DEBUG=0
make;make install
chown -R mysql:mysql /usr/local/webserver/mysql
ln -s /usr/local/webserver/mysql/lib/libmysqlclient.so.18 /usr/lib/libmysqlclient.so.18
echo "/usr/local/webserver/mysql/lib/mysql" >> /etc/ld.so.conf
3. 創建配置文件
#++++++++++++++++++++++++++++++++ multi ++++++++++++++++++++++++++
[mysqld_multi]
mysqld = /usr/local/webserver/mysql/bin/mysqld_safe
mysqladmin = /usr/local/webserver/mysql/bin/mysqladmin
use = root
#password =
log = /data/mysql/multi.log
[client]
#default-character-set = utf8
#++++++++++++++++++++++++++++++++++3306++++++++++++++++++++++++++
[mysqld3306]
user = mysql
port = 3306
socket = /data/mysql/data3306/sock/mysql.sock
pid-file = /data/mysql/data3306/sock/mysql.pid
datadir = /data/mysql/data3306/data
tmpdir = /data/mysql/data3306/tmpdir
big_tables
skip_external_locking
skip-name-resolve
lower_case_table_names = 1
back_log = 100
#default-storage-engine = INNODB
max_connections = 800
max_connect_errors = 100000
interactive_timeout = 172800
connect_timeout = 10
max_allowed_packet = 4M
max_heap_table_size = 128M
tmp_table_size = 128M
max_length_for_sort_data = 4096
net_buffer_length = 8K
sort_buffer_size = 8M
join_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 2M
table_cache = 1024
thread_cache_size = 64
thread_concurrency = 8
query_cache_type = 0
query_cache_size = 64M
query_cache_limit = 1M
#******************************* Logs related settings ***************************
log-error = /data/mysql/data3306/log/error.log
log_warnings
long_query_time = 1
slow_query_log
slow_query_log_file = /data/mysql/data3306/log/slow-query.log
log_queries_not_using_indexes
binlog_cache_size = 8M
max_binlog_size = 512M
log-bin = /data/mysql/data3306/binlog/mysql-bin3306
log-bin-index = /data/mysql/data3306/binlog/mysql-bin3306.index
expire_logs_days = 3
#******************************* Replication related settings **********************
server-id = 3306
report_port = 3306
report_user = repl
slave_net_timeout = 60
innodb_flush_log_at_trx_commit = 2
sync_binlog = 0
binlog-format = mixed
transaction_isolation = REPEATABLE-READ
#******************************* MyISAM Specific options ****************************
key_buffer_size = 32M
bulk_insert_buffer_size = 16M
myisam_sort_buffer_size = 64M
myisam_max_sort_file_size = 1G
myisam_repair_threads = 1
myisam_recover
#***************************** INNODB Specific options ******************************
innodb_file_per_table = 1
innodb_autoinc_lock_mode = 1
innodb_fast_shutdown = 2
innodb_additional_mem_pool_size = 64M
innodb_buffer_pool_size = 5G
innodb_data_home_dir = /data/mysql/data3306/innodb_ts
innodb_data_file_path = ibdata1:256M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 0
innodb_log_buffer_size = 8M
innodb_log_file_size = 128M
#innodb_log_files_in_group = 5
innodb_log_group_home_dir = /data/mysql/data3306/innodb_log
innodb_max_dirty_pages_pct = 20
innodb_lock_wait_timeout = 120
innodb_flush_method=O_DIRECT
#++++++++++++++++++++++++++++++++++3307++++++++++++++++++++++++++
[mysqld3307]
user = mysql
port = 3307
socket = /data/mysql/data3307/sock/mysql.sock
pid-file = /data/mysql/data3307/sock/mysql.pid
datadir = /data/mysql/data3307/data
tmpdir = /data/mysql/data3307/tmpdir
big_tables
skip_external_locking
skip-name-resolve
lower_case_table_names = 1
back_log = 100
#default-storage-engine = INNODB
max_connections = 800
max_connect_errors = 100000
interactive_timeout = 172800
connect_timeout = 10
max_allowed_packet = 4M
max_heap_table_size = 128M
tmp_table_size = 128M
max_length_for_sort_data = 4096
net_buffer_length = 8K
sort_buffer_size = 8M
join_buffer_size = 1M
read_buffer_size = 1M
read_rnd_buffer_size = 2M
table_cache = 1024
thread_cache_size = 64
thread_concurrency = 8
query_cache_type = 0
query_cache_size = 64M
query_cache_limit = 1M
#******************************* Logs related settings ***************************
log-error = /data/mysql/data3307/log/error.log
log_warnings
long_query_time = 1
slow_query_log
slow_query_log_file = /data/mysql/data3307/log/slow-query.log
log_queries_not_using_indexes
binlog_cache_size = 8M
max_binlog_size = 512M
log-bin = /data/mysql/data3307/binlog/mysql-bin3307
log-bin-index = /data/mysql/data3307/binlog/mysql-bin3307.index
expire_logs_days = 3
#******************************* Replication related settings **********************
server-id = 3307
report_port = 3307
report_user = repl
slave_net_timeout = 60
innodb_flush_log_at_trx_commit = 2
sync_binlog = 0
binlog-format = mixed
transaction_isolation = REPEATABLE-READ
#******************************* MyISAM Specific options ****************************
key_buffer_size = 32M
bulk_insert_buffer_size = 16M
myisam_sort_buffer_size = 64M
myisam_max_sort_file_size = 1G
myisam_repair_threads = 1
myisam_recover
#***************************** INNODB Specific options ******************************
innodb_file_per_table = 1
innodb_autoinc_lock_mode = 1
innodb_fast_shutdown = 2
innodb_additional_mem_pool_size = 64M
innodb_buffer_pool_size = 5G
innodb_data_home_dir = /data/mysql/data3307/innodb_ts
innodb_data_file_path = ibdata1:256M:autoextend
innodb_file_io_threads = 4
innodb_thread_concurrency = 0
innodb_log_buffer_size = 8M
innodb_log_file_size = 128M
#innodb_log_files_in_group = 5
innodb_log_group_home_dir = /data/mysql/data3307/innodb_log
innodb_max_dirty_pages_pct = 20
innodb_lock_wait_timeout = 120
innodb_flush_method=O_DIRECT
[mysql]
no-auto-rehash
#prompt=”\\u@\\h : \\d \\r:\\m:\\s>”
prompt="(\\u:MySQL5_10@qzhijun:\R:\m:\\s)[\\d]> "
#tee=”/tmp/query.log”
#pager=”less -i -n -S”
max_allowed_packet = 1G
[mysqldump]
quick
max_allowed_packet = 1G
[mysqld_safe]
open-files-limit = 8192
[myisamchk]
key_buffer = 512M
sort_buffer_size = 128M
read_buffer = 8M
write_buffer = 8M
[mysqlhotcopy]
interactive-timeout
還有幾點需要說明的:
a. 配置文件中寫了兩個mysqld節點,也就是啓用了兩個實例!要是有多個實例,就可以在配置文件加相應的mysqld節點,也可以給定每個實例單個配置,但是個人推薦用一個配置文件。
b. 配置文件中參數比較多,可能有些版本不同導致有些參數不適用,在後面啓動時可能會報錯,請大家多看錯誤日誌!基本上通過查看錯誤日誌能解決90%以上的問題,這也是排除故障的最基礎的方法,大家應該養成這樣的習慣。
c. 錯誤日誌不能完全理解爲,錯誤日誌記錄的全是錯誤日誌,它記錄了錯誤信息、警告信息、服務啓動狀態信息等,這是大部分網友容易誤解的!
d. 這裏的配置文件內容僅供參考,自己可以參考安裝目錄support-files目錄下相關配置文件,根據自己的生產需求來選擇配置文件。
配置文件中對於多實例部分參數說明:
u[mysqld_multi] 節點下相關參數
user參數:該參數爲mysqld_multi命令配置一個統一默認的管理帳號,能夠統一管理旗下所有mysqld服務節點的運行、管理、檢查等相關信息,若在此設置的話,命令方式執行時沒制定就使用此參數的值;
password參數:該參數是對應user的密碼,但是密碼信息我們一般都不寫到配置文件中,以避免泄漏,而是執行命令的時候再輸入;
log:該參數用於記錄mysqld_multi執行命令的日誌信息,以及出錯信息,以便於我們查找問題的根源;
u[mysqld] 節點下相關參數
該節點作爲MySQL的服務節點,是整個配置文件的重點,也是難點,相關的參數調優等都集結在此節點之下。一臺主機部署要多個實例,就涉及到各個實例各自的數據文件如何存放和隔離的問題,處於實例相關的目錄和數據清理方便,以及維護成本更低,減少維護時的出錯概率,我們採用上述樣例配置文件中的目錄結構,以及目錄和數據文件命名方式,接下來我們主要闡述部分參數設置的意義:
user:該參數爲mysqld服務啓動後,mysqld使用何系統帳號運行mysqld服務的問題,不是指mysql授權表中創建的帳號,而是指操作系統級別中的帳號。我們安裝mysql軟件的時候,一般都會創建一個mysql帳號及爲其制定用戶編號,那麼就可以把帳號名稱mysql 或 mysql名稱對應的用戶編號,設置成參數user的值;
port:該參數是指定該服務節點下實例的監聽端口。
其它大部分相關參數這裏不再說明,請參考mysql5.5的官方手冊!
4. 初使化MySQL兩個實例
初使化mysqld3306實例:
/usr/local/webserver/mysql/scripts/mysql_install_db --basedir=/usr/local/webserver/mysql/ --datadir=/data/mysql/data3306/data/ --user=mysql
初使化mysqld3307實例:
/usr/local/webserver/mysql/scripts/mysql_install_db --basedir=/usr/local/webserver/mysql/ --datadir=/data/mysql/data3307/data/ --user=mysql
初使化實例分別指定不同的數據目錄,要注意!
初使化出現如下字樣,說明初使化成功:
when specifying MySQL privileges !
Installing MySQL system tables...
OK
Filling help tables...
OK
....
....
You can start the MySQL daemon with:
cd /usr/local/webserver/mysql/ ; /usr/local/webserver/mysql//bin/mysqld_safe &
You can test the MySQL daemon with mysql-test-run.pl
cd /usr/local/webserver/mysql//mysql-test ; perl mysql-test-run.pl
Please report any problems with the /usr/local/webserver/mysql//scripts/mysqlbug script!
很多網友在安裝mysql時,啓動mysql服務時,總是啓動不成功,很有可能就是各網友朋友不夠細心,MySQL初使化這步沒成功導致!
5. 一切準備就緒,啓動MySQL實例
啓動命令mysqld_multi
命令執行語法:
mysqld_multi [OPTIONS] {start|stop|report} [GNR,GNR,GNR...]
或者
mysqld_multi [OPTIONS] {start|stop|report} [GNR-GNR,GNR,GNR-GNR,...]
示例:
mysqld_multi start 3306,3307
或者
mysqld_multi start 3306-3307
更多mysqld_multi命令的用法請參考官方文檔和網絡上其它的文檔!同時也可以拷貝MySQL安裝目錄下support-files/mysqld_multi.server 腳本來啓動多實例,這裏不再說明!
mysqld_multi start 3306
mysqld_multi start 3307
啓動完成後,查看各實例錯誤日誌文件:
[root@MySQL5_10 ~]# cat /data/mysql/data3306/log/error.log
121019 20:33:37 mysqld_safe Starting mysqld daemon with databases from /data/mysql/data3306/data
121019 20:33:38 InnoDB: The InnoDB memory heap is disabled
121019 20:33:38 InnoDB: Mutexes and rw_locks use InnoDB's own implementation
121019 20:33:38 InnoDB: Compressed tables use zlib 1.2.3
121019 20:33:38 InnoDB: Initializing buffer pool, size = 100.0M
121019 20:33:38 InnoDB: Completed initialization of buffer pool
InnoDB: The first specified data file /data/mysql/data3306/innodb_ts/ibdata1 did not exist:
InnoDB: a new database to be created!
121019 20:33:38 InnoDB: Setting file /data/mysql/data3306/innodb_ts/ibdata1 size to 256 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100 200
121019 20:33:49 InnoDB: Log file /data/mysql/data3306/innodb_log/ib_logfile0 did not exist: new to be created
InnoDB: Setting log file /data/mysql/data3306/innodb_log/ib_logfile0 size to 128 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
121019 20:33:55 InnoDB: Log file /data/mysql/data3306/innodb_log/ib_logfile1 did not exist: new to be created
InnoDB: Setting log file /data/mysql/data3306/innodb_log/ib_logfile1 size to 128 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: 127 rollback segment(s) active.
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
121019 20:34:01 InnoDB: Waiting for the background threads to start
121019 20:34:02 InnoDB: 1.1.6 started; log sequence number 0
121019 20:34:03 [Note] Event Scheduler: Loaded 0 events
121019 20:34:03 [Note] /usr/local/webserver/mysql/bin/mysqld: ready for connections.
Version: '5.5.12-log' socket: '/data/mysql/data3306/sock/mysql.sock' port: 3306 Source distribution
[root@MySQL5_10 ~]# cat /data/mysql/data3307/log/error.log
121019 20:44:47 mysqld_safe mysqld from pid file /data/mysql/data3307/sock/mysql.pid ended
121019 20:47:22 mysqld_safe Starting mysqld daemon with databases from /data/mysql/data3307/data
121019 20:47:22 InnoDB: The InnoDB memory heap is disabled
121019 20:47:22 InnoDB: Mutexes and rw_locks use InnoDB's own implementation
121019 20:47:22 InnoDB: Compressed tables use zlib 1.2.3
121019 20:47:22 InnoDB: Initializing buffer pool, size = 100.0M
121019 20:47:22 InnoDB: Completed initialization of buffer pool
InnoDB: The first specified data file /data/mysql/data3307/innodb_ts/ibdata1 did not exist:
InnoDB: a new database to be created!
121019 20:47:22 InnoDB: Setting file /data/mysql/data3307/innodb_ts/ibdata1 size to 256 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100 200
121019 20:47:33 InnoDB: Log file /data/mysql/data3307/innodb_log/ib_logfile0 did not exist: new to be created
InnoDB: Setting log file /data/mysql/data3307/innodb_log/ib_logfile0 size to 128 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
121019 20:47:40 InnoDB: Log file /data/mysql/data3307/innodb_log/ib_logfile1 did not exist: new to be created
InnoDB: Setting log file /data/mysql/data3307/innodb_log/ib_logfile1 size to 128 MB
InnoDB: Database physically writes the file full: wait...
InnoDB: Progress in MB: 100
InnoDB: Doublewrite buffer not found: creating new
InnoDB: Doublewrite buffer created
InnoDB: 127 rollback segment(s) active.
InnoDB: Creating foreign key constraint system tables
InnoDB: Foreign key constraint system tables created
121019 20:47:46 InnoDB: Waiting for the background threads to start
121019 20:47:47 InnoDB: 1.1.6 started; log sequence number 0
121019 20:47:47 [Note] Recovering after a crash using /data/mysql/data3307/binlog/mysql-bin3307
121019 20:47:47 [Note] Starting crash recovery...
121019 20:47:47 [Note] Crash recovery finished.
121019 20:47:47 [Note] Event Scheduler: Loaded 0 events
121019 20:47:47 [Note] /usr/local/webserver/mysql/bin/mysqld: ready for connections.
Version: '
5.5.12-log' socket: '/data/mysql/data3307/sock/mysql.sock' port: 3307 Source distribution
下面再看看mysqld_multi日誌:
[root@MySQL5_10 ~]# cat /data/mysql/multi.log
Starting MySQL servers
121019 20:33:37 mysqld_safe Logging to '/data/mysql/data3306/log/error.log'.
121019 20:33:37 mysqld_safe Starting mysqld daemon with databases from /data/mysql/data3306/data
mysqld_multi log file version 2.16; run: 五 10月 19 20:35:27 2012
Starting MySQL servers
121019 20:47:22 mysqld_safe Logging to '/data/mysql/data3307/log/error.log'.
121019 20:47:22 mysqld_safe Starting mysqld daemon with databases from /data/mysql/data3307/data
出現上面信息,說明多實例啓動沒有問題!
也可通過查看端口信息:
[root@MySQL5_10 ~]# lsof -i:3306
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
mysqld 3463 mysql 13u IPv4 9377 TCP *:mysql (LISTEN)
[root@MySQL5_10 ~]# lsof -i:3307
COMMAND PID USER FD TYPE DEVICE SIZE NODE NAME
mysqld 9674 mysql 13u IPv4 20787 TCP *:opsession-prxy (LISTEN)
[root@MySQL5_10 ~]# ps aux |grep mysqld |grep -v grep
顯示結果略.........
................
由於51CTO博客不可以發超過8萬字,所以把ps的結果省略了,不然可以看到啓動的參數都是mysqld節點下面設置的相關參數,都能在這裏顯示出來!
我們還可以查看下各實例的監聽端口:
[root@MySQL5_10 ~]# netstat -ntlp |grep mysql
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 3463/mysqld
tcp 0 0 0.0.0.0:3307 0.0.0.0:* LISTEN 9674/mysqld
客戶端登錄各實例:
[root@MySQL5_10 ~]# mysql -S /data/mysql/data3306/sock/mysql.sock
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 4
Server version: 5.5.25-log Source distribution
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(root:MySQL5_10@qzhijun:10:30:46)[(none)]>show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| test |
+--------------------+
4 rows in set (0.03 sec)
(root:MySQL5_10@qzhijun:10:31:07)[(none)]> \q
[root@MySQL5_10 ~]# mysql -S /data/mysql/data3307/sock/mysql.sock
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 2
Server version: 5.5.25-log Source distribution
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
(root:MySQL5_10@qzhijun:10:31:34)[(none)]>
一個簡單和多實例到此OK........