1.關閉防火墻诽里,否則Mysql從機無法找到主機纫溃,查看防火墻狀態(tài)父能,綠色running表示防火墻開啟
[root@localhost ~]# systemctl status firewalld.service
執(zhí)行關閉命令
[root@localhost ~]# systemctl stop firewalld.service
再次執(zhí)行查看防火墻命令
[root@localhost ~]# systemctl status firewalld.service
執(zhí)行開機禁用防火墻自啟命令
[root@localhost ~]# systemctl disable firewalld.service
2 使用docker下載mysql鏡像臣镣,默認下載最mysql最新版本盼理,目前版本號為8.0.13谈山,如果需要其他版本請登錄https://hub.docker.com/進行搜索
[root@localhost ~]# docker pull mysql
3 下載完畢后分別創(chuàng)建/home/docker/mysql/mysql-3306-data、mysql-3307-data 這五個文件夾宏怔,其中mysql-3306-data奏路、mysql-3307-data這兩個文件夾用來保存mysql數(shù)據(jù),否則docker rm 容器id/容器name 都會刪除數(shù)據(jù)庫中的數(shù)據(jù)
[root@localhost ~]# cd /home
[root@localhost home]# mkdir docker
[root@localhost home]# cd docker
[root@localhost docker]# mkdir mysql
[root@localhost docker]# cd mysql
[root@localhost mysql]# mkdir mysql-3306-data
[root@localhost mysql]# mkdir mysql-3307-data
4 再創(chuàng)建mysql-3306.cnf臊诊、mysql-3307.cnf自定義mysql配置文件鸽粉,用來配置mysql
[root@localhost mysql]# touch mysql-3306.cnf
[root@localhost mysql]# touch mysql-3307.cnf
5 編輯自定義mysql配置文件,復制下列代碼
復制分后一定要對比原文Wパ蕖G迸选!
5.1 mysql-3306.cnf文件復制:
[mysqld]
datadir = /var/lib/mysql
server-id = 1
log-bin = mysql-bin
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
5.2 mysql-3307.cnf文件復制:
[mysqld]
datadir = /var/lib/mysql
server-id = 2
log-bin = mysql-bin
sql_mode=STRICT_TRANS_TABLES,NO_ENGINE_SUBSTITUTION
5.3 配置文件說明
5.3.1 本例只是簡單配置壶硅,詳細配置請搜索my.cnf詳細配置威兜,sql_mode值含義請看文章第二部分:sql_mode值的含義
5.3.2 server-id是唯一的,主從不能相同庐椒,server-id為1表示mysql-3306的數(shù)據(jù)庫為主數(shù)據(jù)庫椒舵,server-id為2表示mysql-3307的數(shù)據(jù)庫為從數(shù)據(jù)庫
6 按Esc后,輸入wq保存退出
7 啟動mysql主從容器
docker run --restart=always --name mysql-3306 -v /home/docker/mysql/mysql-3306.cnf:/etc/my.cnf -v /home/docker/mysql/mysql-3306-data:/var/lib/mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
docker run --restart=always --name mysql-3307 -v /home/docker/mysql/mysql-3307.cnf:/etc/my.cnf -v /home/docker/mysql/mysql-3307-data:/var/lib/mysql -p 3307:3306 -e MYSQL_ROOT_PASSWORD=123456 -d mysql
7.4 以下為啟動命令說明和注意事項约谈,屬于延伸閱讀笔宿,有時間和興趣可以看一下,不屬于配置過程棱诱,執(zhí)行配置請直接跳到步驟 7
7.4.1 命令參數(shù):-v /home/docker/mysql/mysql-3306.cnf:/etc/mysql/mysql-3306.cnf 泼橘,將宿主機/home/docker/mysql/目錄下的mysql自定義配置文件mysql-3306.cnf掛載到mysql容器的/etc/my.cnf 文件上,相當于我們將mysql-3306.cnf配置文件的內容映射到mysql容器的/etc/my.cnf 文件上迈勋,這樣mysql容器啟動時就不會加載/etc/mysql/下mysql默認的my.cnf配置文件炬灭,而去加載/etc/下的my.cnf配置文件,而我們自定義的mysql-3306.cnf配置文件中的內容就會生效
7.4.1.1 為何必須掛載到/etc/my.cnf 文件上靡菇,而不是/etc/mysql/my.cnf 文件上重归?因為mysql默認配置文件位置在/etc/mysql/my.cnf,掛在方式無法改變容器中文件內容厦凤,my.conf內容不會改變鼻吮,my.cnf中沒有我們自定義的配置內容,啟動mysql容器會報錯
7.4.2 命令參數(shù):-v /home/docker/mysql/mysql-3306-data:/var/lib/mysql 讓我們回顧一下较鼓,剛才在自定義mysql配置文件中還指定了datadir = /var/lib/mysql椎木,datadir表示數(shù)據(jù)存儲目錄,現(xiàn)在回到該命令中來,該命令是將mysq容器中香椎,mysql配置文件中指定的數(shù)據(jù)存儲目錄/var/lib/mysql下文件的內容共享到宿主機/home/docker/mysql/mysql-3306-data目錄下
7.4.2.1 為何必須掛載 /var/lib/mysql 目錄漱竖?有狀態(tài)容器都有數(shù)據(jù)持久化需求,在容器的生命周期內士鸥,數(shù)據(jù)持久化是持續(xù)的闲孤,包括容器在被停止后,但當容器被刪除后烤礁,數(shù)據(jù)也隨之被刪除了讼积,因此Docker 采用 volume (卷)的形式來向容器提供持久化存儲,如果不設置該命令脚仔,數(shù)據(jù)庫中的數(shù)據(jù)會默認保存在mysql容器中的/var/lib/mysql目錄下勤众,這樣當執(zhí)行 docker rm 容器id/容器name 命令,會丟失數(shù)據(jù)庫中的數(shù)據(jù)
7.4.3 命令參數(shù):-e MYSQL_ROOT_PASSWORD=123456鲤脏,該命令指定mysql容器root用戶的密碼
8 啟動mysql容器以后查看mysql容器狀態(tài)
[root@localhost mysql]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS
f3dd58204c4f mysql "docker-entrypoint..." 5 seconds ago Up 2 seconds
8.1 如果STATUS狀態(tài)是Up表示成功啟動容器们颜,如果STATUS狀態(tài)是Exited (1) 或者 Restarting (1) 表示未能正常啟動,這時候我們需要查看mysql容器日志修改配置文件內容重新運行容器
[root@localhost mysql]# docker logs mysql-3306|less
8.2 查找出問題后停止mysql容器
[root@localhost mysql]# docker stop mysql-3306
8.3 刪除mysql容器
[root@localhost mysql]# docker rm mysql-3306
8.3 重新執(zhí)行步驟 7
9 設置權限猎醇、更新密碼算法窥突、便于使用Navicat連接,分別進入mysql主從容器中
[root@localhost mysql]# docker exec -it mysql-3306 /bin/bash
[root@localhost mysql]# docker exec -it mysql-3307 /bin/bash
9.1 以下操作在mysql-3306容器硫嘶、mysql-3307容器中完全相同阻问,故只展示一遍,實操中需要執(zhí)行兩次
9.1.1 輸入賬號密碼沦疾,密碼為第6部執(zhí)行的命令-e MYSQL_ROOT_PASSWORD=123456称近,該命令指定mysql容器root用戶的密碼
root@1862c89783a0:/# mysql -u root -p
9.1.2 設置權限(為root分配權限,以便可以遠程連接)
mysql> grant all PRIVILEGES on *.* to root@'%' WITH GRANT OPTION;
Query OK, 0 rows affected (0.01 sec)
9.1.3 由于Mysql5.6以上的版本修改了Password算法哮塞,這里需要更新密碼算法刨秆,便于使用Navicat連接,如果密碼不是‘123456’忆畅,請在BY后替換自己的密碼
mysql> ALTER user 'root'@'%' IDENTIFIED WITH mysql_native_password BY'123456';
Query OK, 0 rows affected (0.01 sec)
9.1.4 刷新MySQL的系統(tǒng)權限相關表
mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)
9.1.5 執(zhí)行完畢后退出mysql
mysql> exit
9.16 退出mysql容器
root@1862c89783a0:/# exit
10 使用navicat連接3306,3307
11 主庫mysql-3306上衡未,查詢執(zhí)行sql: SHOW MASTER STATUS ,并復制紅框中的值mysql-bin.000004邻眷、155
12 從庫mysql-3307上眠屎,查詢執(zhí)行sql: STOP SLAVE ,停止slave
13 從庫mysql-3307上,配置主庫連接肆饶,使用root用戶,查詢執(zhí)行sql:
CHANGE MASTER TO MASTER_HOST='192.168.43.2',MASTER_PORT=3306,MASTER_USER='root',MASTER_PASSWORD='123456',MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=155;
[注:,MASTER_LOG_FILE='mysql-bin.000004',MASTER_LOG_POS=155;要和主庫mysql-3306上面SHOW MASTER STATUS岖常,后復制紅框中的值mysql-bin.000004驯镊、155的時候得到的值一致]
14 從庫mysql-3307上,查詢執(zhí)行sql: START SLAVE ,啟動slave
14.1 如果遇到報錯:Slave failed to initialize relay log info structure from the repository
14.2 由于mysql.slave_relay_log_info表中保留了以前的復制信息板惑,導致新從庫啟動時無法找到對應文件橄镜,我們清理掉該表中的記錄就可以了
再次提醒,不要手動刪該表數(shù)據(jù)冯乘,MySQL已經提供命令:RESET SLAVE
RESET SLAVE做了什么:
1洽胶、刪除slave_master_info ,slave_relay_log_info兩個表中數(shù)據(jù)裆馒;
2姊氓、刪除所有relay log文件,并重新創(chuàng)建新的relay log文件喷好;
3翔横、不會改變gtid_executed 或者 gtid_purged的值
在MySQL主從結構下,Slave服務器會產生三種日志文件梗搅,用來保存主庫的二進制日志事件以及relay log已執(zhí)行到的位置和狀態(tài)禾唁。
1、relay log 文件:**由IO thread線程從主庫讀取的二進制日志事件組成无切,該日志被Slave上的SQL thread線程執(zhí)行荡短,從而實現(xiàn)數(shù)據(jù)的復制。
2哆键、master info log:該文件保存slave連接master的狀態(tài)以及配置信息掘托,如用戶名,密碼洼哎,日志執(zhí)行的位置等烫映。在5.6版本之前,都是使用master.info文件噩峦,從5.6開始锭沟,通過在my.cnf 中配置 master-info-repository=TABLE
這些信息會被寫入mysql.slave_master_info
表中,代替原來的master.info文件了
3识补、relay log info log:該文件保存slave上relay log的執(zhí)行位置族淮。在5.6版本之前,都是使用relay-log.info文件凭涂,從5.6開始祝辣,通過在my.cnf中配置 relay-log-info-repository=TABLE
,使用mysql.slave_relay_log_info表代替原來的文件切油,每次當slave上執(zhí)行start slave時蝙斜,就會讀取該表中的位置信息
查詢執(zhí)行sql: RESET SLAVE
14.3 再次執(zhí)行13 從庫mysql-3307上,查詢執(zhí)行sql: START SLAVE 澎胡,啟動slave
15 從庫mysql-3307上孕荠,查詢執(zhí)行sql: SHOW SLAVE STATUS 娩鹉,查看slave狀態(tài),Slave_IO_State的值為Waiting for master to send event,則說明配置成功
16 配置完成稚伍,測試主從復制弯予,在主庫mysql-3306上創(chuàng)建數(shù)據(jù)庫、表个曙,看看是否mysql-3307也同步
3306上執(zhí)行锈嫩,主庫mysql-3306上查詢執(zhí)行sql: CREATE DATABASE test DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
17 然后navicat上刷新mysql-3307,發(fā)現(xiàn)mysql-3307上也創(chuàng)建有test庫了垦搬,說明主從同步成功呼寸,可以接著測試創(chuàng)建表、對表的數(shù)據(jù)進行增刪改進行測試,主庫mysql-3306上查詢執(zhí)行sql:
CREATE TABLE `user` (
`id` int NOT NULL AUTO_INCREMENT ,
`user_name` varchar(50) NULL ,
PRIMARY KEY (`id`)
)
ENGINE=InnoDB
DEFAULT CHARACTER SET=utf8 COLLATE=utf8_general_ci
;
18 注意悼沿,千萬不要直接在mysql-3307從庫中刪除數(shù)據(jù)庫等舔,否則從庫mysql-3307報錯,無法主從同步
18.1 在mysql-3307上糟趾,查詢執(zhí)行sql: SHOW SLAVE STATUS 慌植,向右拖拽,查看Last_SQL_Error狀態(tài)义郑,可以看到mysql-3307從庫無法同步的錯誤
sql_mode值的含義
sql_mode: | 含義 |
---|---|
ONLY_FULL_GROUP_BY | 對于GROUP BY聚合操作蝶柿,如果在SELECT中的列,沒有在GROUP BY中出現(xiàn)非驮,那么將認為這個SQL是不合法的交汤,因為列不在GROUP BY從句中 |
STRICT_TRANS_TABLES | 在該模式下,如果一個值不能插入到一個事務表中劫笙,則中斷當前的操作芙扎,對非事務表不做任何限制** |
NO_ZERO_IN_DATE | 在嚴格模式,不接受月或日部分為0的日期填大。如果使用IGNORE選項戒洼,我們?yōu)轭愃频娜掌诓迦?0000-00-00'。在非嚴格模式允华,可以接受該日期圈浇,但會生成警告。 |
NO_ZERO_DATE | 在嚴格模式靴寂,不要將 '0000-00-00'做為合法日期磷蜀。你仍然可以用IGNORE選項插入零日期。在非嚴格模式百炬,可以接受該日期褐隆,但會生成警告 |
ERROR_FOR_DIVISION_BY_ZERO | 在嚴格模式,在INSERT或UPDATE過程中剖踊,如果被零除(或MOD(X妓灌,0))轨蛤,則產生錯誤(否則為警告)蜜宪。如果未給出該模式虫埂,被零除時MySQL返回NULL。如果用到INSERT IGNORE或UPDATE IGNORE中圃验,MySQL生成被零除警告掉伏,但操作結果為NULL。 |
NO_AUTO_CREATE_USER | 防止GRANT自動創(chuàng)建新用戶澳窑,除非還指定了密碼斧散。 |
NO_ENGINE_SUBSTITUTION | 如果需要的存儲引擎被禁用或未編譯,那么拋出錯誤摊聋。不設置此值時鸡捐,用默認的存儲引擎替代,并拋出一個異常麻裁。 |
mysql5.0以上版本支持三種sql_mode模式:
sql_mode: | 含義 |
---|---|
ANSI | 寬松模式箍镜,對插入數(shù)據(jù)進行校驗,如果不符合定義類型或長度煎源,對數(shù)據(jù)類型調整或截斷保存色迂,報warning警告。 |
TRADITIONAL | 嚴格模式手销,當向mysql數(shù)據(jù)庫插入數(shù)據(jù)時歇僧,進行數(shù)據(jù)的嚴格校驗,保證錯誤數(shù)據(jù)不能插入锋拖,報error錯誤诈悍。用于事物時,會進行事物的回滾兽埃。 |
STRICT_TRANS_TABLES | 嚴格模式侥钳,進行數(shù)據(jù)的嚴格校驗,錯誤數(shù)據(jù)不能插入讲仰,報error錯誤慕趴。 |
注意:自定義mysql配置文件中如果設置sql_mode=ONLY_FULL_GROUP_BY,則執(zhí)行sql時會報錯:
Error Code: 1055. Expression #3 of SELECT list is not in GROUP BY clause and contains nonaggregated column '×××' which is not functionally dependent on columns in GROUP BY clause; this is incompatible with sql_mode=only_full_group_by
所以sql_mode中最好去掉ONLY_FULL_GROUP_BY參數(shù)