-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path15274384746652.html
601 lines (351 loc) · 17.4 KB
/
15274384746652.html
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
<!doctype html>
<html class="no-js" lang="en">
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>
基于 Docker 搭建 MySQL 主从复制 - 秋田君 - Junkman
</title>
<link href="atom.xml" rel="alternate" title="Junkman" type="application/atom+xml">
<link rel="stylesheet" href="asset/css/foundation.min.css" />
<link rel="stylesheet" href="asset/css/docs.css" />
<script src="asset/js/vendor/modernizr.js"></script>
<script src="asset/js/vendor/jquery.js"></script>
<script src="asset/highlightjs/highlight.pack.js"></script>
<link href="asset/highlightjs/styles/github.css" media="screen, projection" rel="stylesheet" type="text/css">
<script>hljs.initHighlightingOnLoad();</script>
<script type="text/javascript">
function before_search(){
var searchVal = 'site:panlw.github.io ' + document.getElementById('search_input').value;
document.getElementById('search_q').value = searchVal;
return true;
}
</script>
</head>
<body class="antialiased hide-extras">
<div class="marketing off-canvas-wrap" data-offcanvas>
<div class="inner-wrap">
<nav class="top-bar docs-bar hide-for-small" data-topbar>
<section class="top-bar-section">
<div class="row">
<div style="position: relative;width:100%;"><div style="position: absolute; width:100%;">
<ul id="main-menu" class="left">
<li id=""><a target="self" href="index.html">Home</a></li>
<li id=""><a target="_self" href="archives.html">Archives</a></li>
</ul>
<ul class="right" id="search-wrap">
<li>
<form target="_blank" onsubmit="return before_search();" action="http://google.com/search" method="get">
<input type="hidden" id="search_q" name="q" value="" />
<input tabindex="1" type="search" id="search_input" placeholder="Search"/>
</form>
</li>
</ul>
</div></div>
</div>
</section>
</nav>
<nav class="tab-bar show-for-small">
<a href="javascript:void(0)" class="left-off-canvas-toggle menu-icon">
<span> Junkman</span>
</a>
</nav>
<aside class="left-off-canvas-menu">
<ul class="off-canvas-list">
<li><a href="index.html">HOME</a></li>
<li><a href="archives.html">Archives</a></li>
<li><a href="about.html">ABOUT</a></li>
<li><label>Categories</label></li>
<li><a href="Infra.html">Infra</a></li>
<li><a href="Coding.html">Coding</a></li>
<li><a href="Modeling.html">Modeling</a></li>
<li><a href="Archtecting.html">Archtecting</a></li>
</ul>
</aside>
<a class="exit-off-canvas" href="#"></a>
<section id="main-content" role="main" class="scroll-container">
<script type="text/javascript">
$(function(){
$('#menu_item_index').addClass('is_active');
});
</script>
<div class="row">
<div class="large-8 medium-8 columns">
<div class="markdown-body article-wrap">
<div class="article">
<h1>基于 Docker 搭建 MySQL 主从复制 - 秋田君</h1>
<div class="read-more clearfix">
<span class="date">2018/5/28</span>
<span>posted in </span>
<span class="posted-in"><a href='Container.html'>Container</a></span>
<span class="comments">
</span>
</div>
</div><!-- article -->
<div class="article-content">
<blockquote>
<p><a href="https://my.oschina.net/u/3773384/blog/1810111">原文地址</a></p>
</blockquote>
<pre><code>本篇博文相对简单,因为是初次使用 Docker,MySQL 的主从复制之前也在 Centos 环境下搭建过,但是也忘的也差不多了,因此本次尝试在 Docker 中搭建。根据网上教程走还是踩了一些坑,不过所幸最终搭建成功,因此记录下来,避免以后踩了重复的坑。
</code></pre>
<h2 id="toc_0">搭建环境</h2>
<p>Centos 7.2 64 位</p>
<p>MySQL 5.7.13</p>
<p>Docker 1.13.1</p>
<p>接下来,我们将会在一台服务器上安装 docker,并使用 docker 运行三个 MySQL 容器,分别为一主两从。</p>
<h2 id="toc_1">安装 docker</h2>
<p>执行命令</p>
<pre><code>[root@VM_0_17_centos ~]# yum install docker
</code></pre>
<p>如果有提示,一路 y 下去</p>
<p>安装成功启动 Docker 后,查看版本</p>
<pre><code>[root@VM_0_17_centos ~]# docker version
Client:
Version: 1.13.1
API version: 1.26
Package version: <unknown>
Go version: go1.8.3
Git commit: 774336d/1.13.1
Built: Wed Mar 7 17:06:16 2018
OS/Arch: linux/amd64
Server:
Version: 1.13.1
API version: 1.26 (minimum version 1.12)
Package version: <unknown>
Go version: go1.8.3
Git commit: 774336d/1.13.1
Built: Wed Mar 7 17:06:16 2018
OS/Arch: linux/amd64
Experimental: false
</code></pre>
<p>出现版本信息,则安装成功</p>
<h2 id="toc_2">启动 Docker</h2>
<p>启动 Docker 并设置为开机自启动</p>
<pre><code>[root@VM_0_17_centos ~]# systemctl start docker.service
[root@VM_0_17_centos ~]# systemctl enable docker.service
</code></pre>
<h2 id="toc_3">安装 MySQL</h2>
<p>使用 Docker 拉取 MySQL 镜像</p>
<pre><code>[root@VM_0_17_centos ~]# docker pull mysql:5.7.13
</code></pre>
<h2 id="toc_4">运行主容器</h2>
<pre><code>[root@VM_0_17_centos ~]# docker run --name master -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.13
</code></pre>
<p>--name 为容器指定名称,这里是 master</p>
<p>-p 将容器的指定端口映射到主机的指定端口,这里是将容器的 3306 端口映射到主机的 3306 端口</p>
<p>-e 设置环境变量,这里是指定 root 账号的密码为 root</p>
<p>-d 后台运行容器,并返回容器 ID</p>
<p>mysql:5.7.13 指定运行的 mysql 版本</p>
<h2 id="toc_5">检验是否启动成功</h2>
<p>docker ps -a 显示所有的容器,包括未运行的</p>
<pre><code>[root@VM_0_17_centos ~]# docker ps -a
ee86c19336f8 mysql:5.7.13 "docker-entrypoint..." About an hour ago Up About an hour 0.0.0.0:3306->3306/tcp master
</code></pre>
<p>注意,是 UP 状态,表示正在运行中</p>
<p>开放 3306 端口</p>
<pre><code>[root@VM_0_17_centos ~]# firewall-cmd --zone=public --add-port=3306/tcp --permanent
[root@VM_0_17_centos ~]# firewall-cmd --reload
</code></pre>
<p>--permanent 永久开启,避免下次开机需要再次手动开启端口</p>
<p>使用 Navicat 连接测试</p>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/114916_0h3I_3773384.png" alt=""/></p>
<p>MySQL 主容器已经启动成功</p>
<h2 id="toc_6">创建主容器的复制账号</h2>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/120249_0ZQx_3773384.png" alt=""/></p>
<p>使用 Navicat 友好的图像化界面执行 SQL</p>
<pre><code>GRANT REPLICATION SLAVE ON *.* to 'backup'@'%' identified by 'backup';
show grants for 'backup'@'%';
</code></pre>
<p>出现如下信息表示授权成功</p>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/121018_Vtxn_3773384.png" alt=""/></p>
<h2 id="toc_7">修改 MySQL 配置环境</h2>
<p>创建配置文件目录</p>
<p>目录结构如下</p>
<p>/usr/local/mysql/master</p>
<p>/usr/local/mysql/slave1</p>
<p>/usr/local/mysql/slave2</p>
<p>拷贝一份 MySQL 配置文件</p>
<pre><code>[root@VM_0_17_centos local]# docker cp master:/etc/mysql/my.cnf /usr/local/mysql/master/my.cnf
</code></pre>
<p>进到 master 目录下,已存在拷贝的 my.cnf</p>
<pre><code>[root@VM_0_17_centos master]# ll
total 4
-rw-r--r-- 1 root root 1801 May 10 10:27 my.cnf
</code></pre>
<p>修改 my.cnf,在 [mysqld] 节点最后加上后保存</p>
<pre><code>log-bin=mysql-bin
server-id=1
</code></pre>
<p>log-bin=mysql-bin 使用 binary logging,mysql-bin 是 log 文件名的前缀</p>
<p>server-id=1 唯一服务器 ID,非 0 整数,不能和其他服务器的 server-id 重复</p>
<p>将修改后的文件覆盖 Docker 中 MySQL 中的配置文件</p>
<pre><code>[root@VM_0_17_centos master]# docker cp /usr/local/mysql/master/my.cnf master:/etc/mysql/my.cnf
</code></pre>
<p>重启 mysql 的 docker , 让配置生效</p>
<pre><code>[root@VM_0_17_centos master]# docker restart master
</code></pre>
<p>启动后,重新测试连接,连接成功表示主容器配置成功</p>
<h2 id="toc_8">运行 MySQL 从容器</h2>
<p>首先运行从容器</p>
<pre><code>[root@VM_0_17_centos ~]# docker run --name slave1 -p 3307:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:5.7.13
</code></pre>
<p>与主容器相似,拷贝配置文件至 slave1 目录修改后覆盖回 Docker 中</p>
<pre><code>log-bin=mysql-bin
server-id=2
</code></pre>
<p>别忘记,重启 slave1 容器,使配置生效</p>
<h2 id="toc_9">配置主从复制</h2>
<p>使用 Navicat 连接 slave1 后新建查询,执行以下 SQL</p>
<pre><code>CHANGE MASTER TO
MASTER_HOST='ip',
MASTER_PORT=3306,
MASTER_USER='backup',
MASTER_PASSWORD='backup';
START SLAVE;
</code></pre>
<p>MASTER_HOST 填 Navicat 连接配置中的 ip 应该就可以</p>
<p>MASTER_PORT 主容器的端口</p>
<p>MASTER_USER 同步账号的用户名</p>
<p>MASTER_PASSWORD 同步账号的密码</p>
<h2 id="toc_10">检查是否配置成功</h2>
<pre><code>show slave status;
</code></pre>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/123902_gnvI_3773384.png" alt=""/></p>
<p>Slave_IO_State 如果是 Waiting for master to send event,那么就成功一半了,如果是 Connecting to master,基本就是配置失败了,建议重新检查下配置,具体失败的原因可以查看日志追踪</p>
<pre><code>[root@VM_0_17_centos master]# docker logs slave -f
</code></pre>
<p>我遇到的是 MASTER_USER 和 MASTER_PASSWORD 是否手打输错了,贴出错误日志</p>
<pre><code>2018-05-10T02:57:00.688887Z 11 [ERROR] Slave I/O for channel '': error connecting to master 'bakcup@ip:3306' - retry-time: 60 retries: 2, Error_code: 1045
2018-05-10T02:58:00.690476Z 11 [ERROR] Slave I/O for channel '': error connecting to master 'bakcup@ip:3306' - retry-time: 60 retries: 3, Error_code: 1045
</code></pre>
<p>注意看日志中的 bakcup,解决方法如下</p>
<pre><code>STOP SLAVE;
CHANGE MASTER TO
MASTER_HOST='连接Navicat的ip',
MASTER_PORT=正确的端口,
MASTER_USER='正确的用户名',
MASTER_PASSWORD='正确的密码';
START SLAVE;
</code></pre>
<p>接着上文,我们说成功一半,并没有说成功了,那么另一半在于 Slave_IO_Running 与 Slave_SQL_Running</p>
<p>如果都是 Yes,那么恭喜你,可以测试主从复制的效果了,如果有一个不是 Yes,一半是重启从容器后,事务回滚引起的,那么给出解决方法如下</p>
<pre><code>stop slave ;
set GLOBAL SQL_SLAVE_SKIP_COUNTER=1;
start slave ;
</code></pre>
<p>执行后,再次观察三个关键字段应该就都没问题了</p>
<p>至此,一主一从已经搭建完成,再添加从实例的方式与上文一致,这里就不在赘述了。</p>
<h2 id="toc_11">测试主从复制</h2>
<p>首先,在主实例中创建一个测试数据库</p>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/130207_7Ty1_3773384.png" alt=""/></p>
<p>打开(刷新)从实例,可见 test 库已存在</p>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/130133_ITNO_3773384.png" alt=""/></p>
<p>在 test 库中创建一个表 t_test,添加一个 id 测试字段</p>
<p>向表中添加几个数据</p>
<p><img src="https://static.oschina.net/uploads/space/2018/0510/130357_IEZg_3773384.png" alt=""/></p>
<p>刷新从库,可见 t_test 表及其中 1、2、3、4 数据已存在</p>
<p>至此,一个具备主从复制的一主两从的 MySQL 就已搭建完成。</p>
</div>
<div class="row">
<div class="large-6 columns">
<p class="text-left" style="padding:15px 0px;">
<a href="15274389377310.html"
title="Previous Post: Kubernetes API 使用文档">« Kubernetes API 使用文档</a>
</p>
</div>
<div class="large-6 columns">
<p class="text-right" style="padding:15px 0px;">
<a href="15274377762013.html"
title="Next Post: Never touch your local /etc/hosts file in OS X again">Never touch your local /etc/hosts file in OS X again »</a>
</p>
</div>
</div>
<div class="comments-wrap">
<div class="share-comments">
<script type="text/javascript" src="//s7.addthis.com/js/300/addthis_widget.js#pubid=ra-5ae58078c0d7b2ab"></script>
</div>
</div>
</div><!-- article-wrap -->
</div><!-- large 8 -->
<div class="large-4 medium-4 columns">
<div class="hide-for-small">
<div id="sidebar" class="sidebar">
<div id="site-info" class="site-info">
<div class="site-a-logo"><img src="./asset/img/logo.jpg" /></div>
<h1>Junkman</h1>
<div class="site-des">“拾荒者”一词来自凯文・凯利的《失控》中关于机器学习的故事(“收集癖好机”如何完成他的收集工作)。</div>
<div class="social">
<a target="_blank" class="github" target="_blank" href="https://github.com/panlw/" title="GitHub">GitHub</a>
<a target="_blank" class="rss" href="atom.xml" title="RSS">RSS</a>
</div>
</div>
<div id="site-categories" class="side-item ">
<div class="side-header">
<h2>Categories</h2>
</div>
<div class="side-content">
<p class="cat-list">
<a href="Infra.html"><strong>Infra</strong></a>
<a href="Coding.html"><strong>Coding</strong></a>
<a href="Modeling.html"><strong>Modeling</strong></a>
<a href="Archtecting.html"><strong>Archtecting</strong></a>
</p>
</div>
</div>
<div id="site-categories" class="side-item">
<div class="side-header">
<h2>Recent Posts</h2>
</div>
<div class="side-content">
<ul class="posts-list">
<li class="post">
<a href="15517999043443.html">The Art of Crafting Architectural Diagrams</a>
</li>
<li class="post">
<a href="15517997955971.html">为什么说我们需要软件架构图?</a>
</li>
<li class="post">
<a href="15516128677869.html">DNS Servers That Offer Privacy and Filtering</a>
</li>
<li class="post">
<a href="15516123108194.html">Airbnb's Migration from Monolith to Services</a>
</li>
<li class="post">
<a href="15516097487470.html">Events As First-Class Citizens</a>
</li>
</ul>
</div>
</div>
</div><!-- sidebar -->
</div><!-- hide for small -->
</div><!-- large 4 -->
</div><!-- row -->
<div class="page-bottom clearfix">
<div class="row">
<p class="copyright">Copyright © 2015
Powered by <a target="_blank" href="http://www.mweb.im">MWeb</a>,
Theme used <a target="_blank" href="http://github.com">GitHub CSS</a>.</p>
</div>
</div>
</section>
</div>
</div>
<script src="asset/js/foundation.min.js"></script>
<script>
$(document).foundation();
function fixSidebarHeight(){
var w1 = $('.markdown-body').height();
var w2 = $('#sidebar').height();
if (w1 > w2) { $('#sidebar').height(w1); };
}
$(function(){
fixSidebarHeight();
})
$(window).load(function(){
fixSidebarHeight();
});
</script>
<script src="asset/chart/all-min.js"></script><script type="text/javascript">$(function(){ var mwebii=0; var mwebChartEleId = 'mweb-chart-ele-'; $('pre>code').each(function(){ mwebii++; var eleiid = mwebChartEleId+mwebii; if($(this).hasClass('language-sequence')){ var ele = $(this).addClass('nohighlight').parent(); $('<div id="'+eleiid+'"></div>').insertAfter(ele); ele.hide(); var diagram = Diagram.parse($(this).text()); diagram.drawSVG(eleiid,{theme: 'simple'}); }else if($(this).hasClass('language-flow')){ var ele = $(this).addClass('nohighlight').parent(); $('<div id="'+eleiid+'"></div>').insertAfter(ele); ele.hide(); var diagram = flowchart.parse($(this).text()); diagram.drawSVG(eleiid); } });});</script>
<script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script><script type="text/x-mathjax-config">MathJax.Hub.Config({TeX: { equationNumbers: { autoNumber: "AMS" } }});</script>
</body>
</html>