最近在学习Docker,看了《Docker从入门到实践》这本书,做了一些笔记,在这边整理成思维导图的方式,分享一下。
博客地址:https://win-man.github.io/
公众号:欢迎关注
最近在学习Docker,看了《Docker从入门到实践》这本书,做了一些笔记,在这边整理成思维导图的方式,分享一下。
博客地址:https://win-man.github.io/
公众号:欢迎关注
MariaDB-10.1.14安装步骤与MySQL-5.6一致,只是一些在MySQL中的参数,在MarIaDB中不能使用或者被忽略。在QData的参数模板中,以下参数会导致数据库初始化话失败:1
2
3
4
5
6gtid-mode=on # GTID only
enforce-gtid-consistency=true # GTID only
slave_parallel_type=LOGICAL_CLOCK
innodb_undo_log_truncate=ON
log_timestamps=SYSTEM
slave_preserve_commit_order=ON
以下参数会使数据库初始化的过程中出现警告:1
2
3
4
5
6slave_pending_jobs_size_max=128M
table_open_cache = 4096
binlog-rows-query-log-events
master-info-repository
relay-log-info-repository
slave-parallel-workers
使用的参数模板如下: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[client]
loose_default-character-set = utf8
port=3306
socket=/home/mysql/data/mysqldata1/sock/mysql.sock
user=admin
[mysqldump]
quick
max_allowed_packet = 2G
default-character-set = utf8
[mysql]
no-auto-rehash
show-warnings
prompt="\\u@\\h : \\d \\r:\\m:\\s> "
default-character-set = utf8
[myisamchk]
key_buffer = 512M
sort_buffer_size = 512M
read_buffer = 8M
write_buffer = 8M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
user=mysql
open-files-limit = 65535
[mysqld]
#large-pages
#***********************************common parameters******************************
read_only=on
#memlock
default-storage-engine = INNODB
character-set-server=utf8
collation_server = utf8_bin
user=mysql
port=3306
socket=/home/mysql/data/mysqldata1/sock/mysql.sock
pid-file=/home/mysql/data/mysqldata1/sock/mysql.pid
datadir=/home/mysql/data/mysqldata1/mydata
tmpdir=/home/mysql/data/mysqldata1/tmpdir
skip-name-resolve
skip_external_locking
lower_case_table_names=1
event_scheduler=0
back_log=512
default-time-zone='+8:00'
max_connections = 3000
max_connect_errors=99999
max_allowed_packet = 64M
#slave_pending_jobs_size_max=128M
max_heap_table_size = 8M
max_length_for_sort_data = 16k
wait_timeout=172800
interactive_timeout=172800
net_buffer_length = 8K
read_buffer_size = 2M
read_rnd_buffer_size = 2M
sort_buffer_size = 2M
join_buffer_size = 4M
binlog_cache_size = 2M
#table_open_cache = 4096
table_open_cache_instances = 2
table_definition_cache = 4096
thread_cache_size = 512
tmp_table_size = 8M
query_cache_size=0
query_cache_type=OFF
explicit_defaults_for_timestamp=ON
#******************************* Logs related settings ***************************
log-error=/home/mysql/data/mysqldata1/log/error.log
long_query_time = 1
slow_query_log
slow_query_log_file=/home/mysql/data/mysqldata1/slowlog/slow-query.log
log_slow_slave_statements
#log_queries_not_using_indexes
#******************************* Replication related settings **********************
#### For Master
server-id=3306191
log-bin=/home/mysql/data/mysqldata1/binlog/mysql-bin
binlog-format=ROW
binlog-checksum=CRC32
#binlog-rows-query-log-events=1
max_binlog_size = 512M
expire_logs_days=15
sync_binlog=1
master-verify-checksum=1
#master-info-repository=TABLE
auto_increment_increment=2
auto_increment_offset=2
#### For Slave
relay-log=/home/mysql/data/mysqldata1/relaylog/mysql-relay-bin
#relay-log-info-repository=TABLE
relay-log-recovery=1
#slave-skip-errors=1022,1032,1062,1236
slave-sql-verify-checksum=1
log_bin_trust_function_creators=1
log_slave_updates=1
slave-net-timeout=10
skip-slave-start
#******************************* MyISAM Specific options ****************************
key_buffer_size = 8M
bulk_insert_buffer_size = 8M
myisam_sort_buffer_size = 64M
myisam_max_sort_file_size = 10G
myisam_repair_threads = 1
myisam_recover_options=force
# ***************************** INNODB Specific options ****************************
#### Data options
#innodb_data_home_dir = /home/mysql/data/mysqldata1/innodb_ts
innodb_data_file_path = ibdata1:2048M:autoextend
innodb_file_per_table
innodb_file_format = barracuda
innodb_file_format_max = barracuda
innodb_file_format_check = ON
innodb_strict_mode = 1
innodb_flush_method = O_DIRECT
innodb_checksum_algorithm=crc32
innodb_autoinc_lock_mode=2
#### Buffer Pool options
innodb_buffer_pool_size = 4G
innodb_buffer_pool_instances = 2
innodb_max_dirty_pages_pct = 75
innodb_adaptive_flushing = ON
innodb_flush_neighbors = 0
innodb_lru_scan_depth = 4096
#innodb_change_buffering = inserts
innodb_old_blocks_time = 1000
#### Redo options
innodb_log_group_home_dir = /home/mysql/data/mysqldata1/innodb_log
innodb_log_buffer_size = 64M
innodb_log_file_size = 2G
innodb_log_files_in_group = 2
innodb_flush_log_at_trx_commit = 1
innodb_fast_shutdown = 2
innodb_support_xa = ON
#### Transaction options
innodb_thread_concurrency = 64
innodb_lock_wait_timeout = 120
innodb_rollback_on_timeout = 1
transaction_isolation = READ-COMMITTED
#### IO options
innodb_read_io_threads = 8
innodb_write_io_threads = 16
innodb_io_capacity = 20000
innodb_use_native_aio = 1
#### Undo options
innodb_undo_directory = /home/mysql/data/mysqldata1/undo/
innodb_undo_tablespaces=16
innodb_purge_threads = 4
innodb_purge_batch_size = 512
innodb_max_purge_lag = 65536
#### 5.6/5.7 GTID
#gtid-mode=on # GTID only
#enforce-gtid-consistency=true # GTID only
#### mysql 5.7
#super_read_only=on
secure_file_priv=/data2/
#slave_parallel_workers=16
#slave_parallel_type=LOGICAL_CLOCK
#innodb_undo_log_truncate=ON
#log_timestamps=SYSTEM
#slave_preserve_commit_order=ON
#### mariadb
gtid_strict_mode=on
gtid_domain_id=191
#### galera
wsrep_on=on
wsrep_provider=/usr/local/mysql/lib/galera/libgalera_smm.so
wsrep_provider_options="gcache.size=1G"
wsrep_cluster_name=wqglr_0001
wsrep_cluster_address=gcomm://10.10.90.167:4567,10.10.90.174:4567,10.10.90.181:4567
wsrep_node_name = node3
wsrep_node_address=10.10.90.181:4567
#
#wsrep_sst_method=xtrabackup-v2
#wsrep_sst_auth="xtrabackup:xtrabackuppass"
#wsrep_slave_threads=16
#
#innodb_support_xa = OFF
#sync_binlog=0
#innodb_flush_log_at_trx_commit = 0
创建目录
1 | mkdir -p /data2/mysqldata1/{binlog,conf,innodb_log,innodb_ts,log,mydata,relaylog,slowlog,sock,tmpdir,undo} |
下载二进制安装包,并上传到对应位置
将安装包解压至指定目录,并建立软链至/usr/local
1 | tar -zxvf mariadb-10.1.14-linux-x86_64 -c /home/mysql/program/ |
添加用户以及用户组
1 | groupadd mysql |
更改目录权限
1 | chown -R mysql:mysql /data/mysqldata1 |
填写配置文件
将上面的配置文件内容写到/etc/my.cnf中
1 | cd /usr/local/mysql |
验证安装成功:
查看是否有两个OK
添加service启动方式
1 | cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld |
尝试启动数据库,验证数据库正常
1 | service mysqld start |
按照相同的步骤安装三个节点
安装步骤:
在配置文件中填写galera集群的配置参数
一下为最基础的参数配置,一些调优等的配置参数不列在这边
1 | gtid_strict_mode=on |
启动第一个节点
galera集群启动第一个节点的时候需要加上,–wsrep-new-cluster来初始化一个集群,这个只需要在第一个节点第一次启动的时候添加,之后该节点启动时不需要添加该参数,因为这个参数的表示初始化一个新的集群,每次添加该参数,都会初始化一个新的集群
1 | cd /usr/local/mysql/bin |
进入数据库检查,集群状态 show status like ‘%wsrep_%’
1 | root@localhost : (none) 11:00:08> show status like '%wsrep_%'; |
重点关注几个状态:wsrep_connected=on
表示链接已开启wsrep_local_index=1
表示集群中的索引值wsrep_cluster_size=3
表示集群中节点的数量wsrep_incoming_addresses =0.10.90.181:3306,10.10.90.167:3306,10.10.90.174:3306
集群中节点的访问地址
安装步骤
在配置文件中填写galera集群的配置参数
一下为最基础的参数配置,一些调优等的配置参数不列在这边
1 | gtid_strict_mode=on |
启动节点
1 | service mysqld start |
进入数据库检查,集群状态 show status like ‘%wsrep_%’
仲裁节点不需要初始化数据库,不需要进行配置,但是数据目录需要创建,数据库程序需要部署
启动仲裁节点
1 | cd /usr/local/mysql/bin |
检查仲裁节点加入情况
node1或者node2上show status like ‘%wsrep_cluster%’;查看集群节点数量,发现集群节点数量增加1
1 | root@localhost : (none) 01:23:30> show status like '%wsrep_cluster%'; |
在node1上:1
2
3
4create database test1;
use test1;
create table test1(id int primary key auto_increment,name varchar(20));
insert into test1(`name`) values('test1');
在node2上1
2
3
4create database test2;
use test2;
create table test1(id int primary key auto_increment,name varchar(20));
insert into test1(`name`) values('test1');
在两个节点上查询数据,发现数据复制正常
错误日志:1
2
3
4
5
6
7
8
92018-01-09 16:19:28 140122035881856 [Warning] 'table-open-cache-instances' is MySQL 5.6 compatible option. Not used or needed in MariaDB.
2018-01-09 16:19:28 140122035881856 [Note] /usr/local/mysql/bin/mysqld (mysqld 10.1.14-MariaDB) starting as process 31625 ...
2018-01-09 16:19:28 140122035881856 [Note] WSREP: Read nil XID from storage engines, skipping position init
2018-01-09 16:19:28 140122035881856 [Note] WSREP: wsrep_load(): loading provider library '/usr/local/mysql/lib/galera/libgalera_smm.so'
2018-01-09 16:19:28 140122035881856 [ERROR] WSREP: wsrep_load(): dlopen(): libssl.so.6: cannot open shared object file: No such file or directory
2018-01-09 16:19:28 140122035881856 [ERROR] WSREP: wsrep_load(/usr/local/mysql/lib/galera/libgalera_smm.so) failed: Invalid argument (22). Reverting to no provider.
2018-01-09 16:19:28 140122035881856 [Note] WSREP: Read nil XID from storage engines, skipping position init
2018-01-09 16:19:28 140122035881856 [Note] WSREP: wsrep_load(): loading provider library 'none'
2018-01-09 16:19:28 140122035881856 [ERROR] Aborting
解决方案: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#ldd libgalera_smm.so
linux-vdso.so.1 => (0x00007ffda1bdc000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fabbb35f000)
librt.so.1 => /lib64/librt.so.1 (0x00007fabbb157000)
libssl.so.6 => not found
libcrypto.so.6 => not found
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fabbae4e000)
libm.so.6 => /lib64/libm.so.6 (0x00007fabbab4b000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fabba935000)
libc.so.6 => /lib64/libc.so.6 (0x00007fabba574000)
/lib64/ld-linux-x86-64.so.2 (0x00007fabbbade000)
[root@node2 /lib64]
#cd /usr/lib64
[root@node2 /usr/lib64]
#ll libssl*
-rwxr-xr-x. 1 root 272536 Nov 20 2015 libssl3.so
lrwxrwxrwx. 1 root 16 Dec 27 15:31 libssl.so -> libssl.so.1.0.1e
lrwxrwxrwx. 1 root 16 Dec 27 15:30 libssl.so.10 -> libssl.so.1.0.1e
-rwxr-xr-x. 1 root 449864 Jun 29 2015 libssl.so.1.0.1e
[root@node2 /usr/lib64]
#ln -s libssl.so.1.0.1e libssl.so.6
[root@node2 /usr/lib64]
#ll libcrypto*
lrwxrwxrwx. 1 root 19 Dec 27 15:31 libcrypto.so -> libcrypto.so.1.0.1e
lrwxrwxrwx. 1 root 19 Dec 27 15:30 libcrypto.so.10 -> libcrypto.so.1.0.1e
-rwxr-xr-x. 1 root 2012880 Jun 29 2015 libcrypto.so.1.0.1e
[root@node2 /usr/lib64]
#ln -s libcrypto.so.1.0.1e libcrypto.so.6
#ldd /usr/local/mysql/lib/galera/libgalera_smm.so
linux-vdso.so.1 => (0x00007ffecdbad000)
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007fe44169e000)
librt.so.1 => /lib64/librt.so.1 (0x00007fe441496000)
libssl.so.6 => /lib64/libssl.so.6 (0x00007fe441228000)
libcrypto.so.6 => /lib64/libcrypto.so.6 (0x00007fe440e41000)
libstdc++.so.6 => /lib64/libstdc++.so.6 (0x00007fe440b39000)
libm.so.6 => /lib64/libm.so.6 (0x00007fe440836000)
libgcc_s.so.1 => /lib64/libgcc_s.so.1 (0x00007fe440620000)
libc.so.6 => /lib64/libc.so.6 (0x00007fe44025f000)
/lib64/ld-linux-x86-64.so.2 (0x00007fe441e1d000)
libgssapi_krb5.so.2 => /lib64/libgssapi_krb5.so.2 (0x00007fe440012000)
libkrb5.so.3 => /lib64/libkrb5.so.3 (0x00007fe43fd2d000)
libcom_err.so.2 => /lib64/libcom_err.so.2 (0x00007fe43fb29000)
libk5crypto.so.3 => /lib64/libk5crypto.so.3 (0x00007fe43f8f6000)
libdl.so.2 => /lib64/libdl.so.2 (0x00007fe43f6f2000)
libz.so.1 => /lib64/libz.so.1 (0x00007fe43f4dc000)
libkrb5support.so.0 => /lib64/libkrb5support.so.0 (0x00007fe43f2cc000)
libkeyutils.so.1 => /lib64/libkeyutils.so.1 (0x00007fe43f0c8000)
libresolv.so.2 => /lib64/libresolv.so.2 (0x00007fe43eeae000)
libselinux.so.1 => /lib64/libselinux.so.1 (0x00007fe43ec88000)
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007fe43ea27000)
liblzma.so.5 => /lib64/liblzma.so.5 (0x00007fe43e802000)
因为我们的galera集群的配置参数中没有指定:1
2#wsrep_sst_method=xtrabackup-v2
#wsrep_sst_auth="xtrabackup:xtrabackuppass"
所以galeta集群在进行sst的时候是通过默认的的rsync方式同步的,但是在这种方式下,不能自定义innodb_data_home_dir和innodb_log_home_dir,这是MariaDB Galera的BUG,如果要自定义这两个参数,可以选择xtrabackup的方式。
wsrep_sst_method可以指定为mysqldump,xtrabackup,rsync三种,xtrabackup的方式锁表时间最短
博客地址:https://win-man.github.io/
公众号:欢迎关注
博客地址:https://win-man.github.io/
公众号:欢迎关注
NFS(Network File System)这个网络文件系统,最大的功能是通过网络,使得在不同的机器之间共享文件。通过NFS可以将另一台机器的某个目录挂载到本机的某个目录下,在使用的时候挂载过来的目录就像在本地一样。极大的方便了多台服务器之间的文件共享。
在提到NFS服务的时候,都会提到RPC服务,那么什么是RPC服务,为什么需要RPC服务呢。
首先RPC是Remote Procedure Call的缩写,及远程过程调用。其次关于为什么要RPC服务是因为,NFS服务在启动的时候对于端口的选择是随机的,NFS在启动的时候回随机选择小于1024的端口进行数据的传输。那么在客户端连接到NFS服务器的时候,怎么知道应该通过哪个端口进行连接呢。这个时候就需要RPC服务出现了,RPC的主要功能就是记录每个NFS服务所对应的端口号,并将对应的端口号发送给客户端,客户端根据获得的端口号进行连接。
客户端连接NFS服务的过程:
配置文件中的格式:1
<输出目录> [客户端1(权限)] [客户端2(权限)] ...
输出目录
指定共享的文件目录
客户端
指定可以访问共享资源的客户端
权限
检查服务器是否安装了nfs-util和rpcbind两个包
1 | [root@d146bbc8-94a2-42c4-8eaa-3fb3264fd176 ~]# rpm -qa | grep nfs |
填写/etc/exports配置文件
1 | mkdir -p /nfs/{test1,test2,test3,test4,test5} |
exports配置文件中都有默认权限配置,如果我们想查看默认的配置是什么,可以查看/var/lib/nfs/etab
文件,该文件中完整的记录了NFS共享资源的所有配置1
2
3
4/nfs/test2 10.10.30.247(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
/nfs/test1 10.10.30.247(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
/nfs/test3 10.10.30.0/24(rw,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
/nfs/test2 *(ro,sync,wdelay,hide,nocrossmnt,secure,root_squash,no_all_squash,no_subtree_check,secure_locks,acl,anonuid=65534,anongid=65534)
启动RPC服务
1 | [root@d146bbc8-94a2-42c4-8eaa-3fb3264fd176 ~]# /etc/init.d/rpcbind start |
启动NFS服务
1 | [root@d146bbc8-94a2-42c4-8eaa-3fb3264fd176 ~]# /etc/init.d/nfs start |
修改/etc/exports文件
如果我们在启动NFS服务之后,又修改了 exports
文件的话怎么办,是不是需要重新启动NFS服务才能使的这些配置生效,答案当然是否定的,这样多麻烦。我们有 exportfs
命令。
1 | exportfs [-aruv] |
1 | [root@6a192e7f-a43d-4b57-9573-ca740e3b5f0d ~]# showmount -e 10.10.30.250 |
1 | showmount [-ae] [hostname|IP] |
挂载NFS目录
1 | [root@6a192e7f-a43d-4b57-9573-ca740e3b5f0d ~]# mkdir -p /nfs/local/{test1,test2,test3} |
查看挂载情况
1 | [root@6a192e7f-a43d-4b57-9573-ca740e3b5f0d ~]# df -h |
我们知道在Linux系统中的文件,都有访问权限,可以指定用户访问,那么我通过NFS访问文件权限是如何设定的呢。比如我再NFS server上有一个文件的属主与属组都是gangshen,那我再client端普通用户user1访问这个文件,可以做修改吗?如果是使用root用户访问这个文件,可以做修改吗?
NFS文件系统的权限访问的原则是:服务器端会以客户端的用户UID与GID等身份来尝试读取服务器端的文件系统
以下是NFS是如何判断是否一个文件可写的步骤:
根据上述步骤的话,可以想到一种情况,如果我client端是通过root账户连接的,那我是不是对所有的文件具有可读、可写权限。这个的话,就需要重新来看下/etc/exports这个配置文件了。在exports文件中,设定权限的时候可以指定no_root_squash、root_squash、all_squash,这三个就是控制,我client连接上来的用户,最终在server端会以哪个用户进行访问。默认情况下是设置为root_squash,就是说如果client以root用户连接上来的话,server端会将该用户转换为匿名用户进行访问。很明显no_root_squash这个选项就是说不转换成匿名用户,all_squash这个选项是指定无论client用什么账户连接上来,都会被转换成匿名用户。
博客地址:https://win-man.github.io/
公众号:欢迎关注
学习Linux的时候,避不开的就是需要学习Linux中的分区。学习Linux的分区,有很多概念性的东西需要学习,比如分区类型啊,文件系统类型啊…等等,对于我来说,并不是很喜欢这种概念性的东西,上来一大段文字对于我一点都不友好。所以整理了一篇笔记,记录怎么对Linux中的磁盘进行分区、创建文件系统以及挂载。首先能实操使用,接着再慢慢理解其中的内容。
操作系统:CentOS6.6
fdisk可用于查看硬盘分区情况,也可以使用fdisk进行分区。
选项:1
2
3
4
5-b SECTOR_SIZE:指定每个分区大小
-l:列出指定硬盘的分区情况
-s PARTITION:输出指定分区的大小,单位为块
-u:在列出硬盘分区情况的时候,使用块为单位列出分区大小而不是以柱面为单位
-v:显示版本信息
子选项:1
2
3
4
5
6
7
8p:print,显示已有分区
n:new,创建
d:delete,删除
w:write,写入磁盘并退出
q:quit,放弃更新并退出
m:获取帮助
l:列表所分区id
t:调整分区id
**选项:1
2
3
4
5-a:通知内核重新读取硬盘分区表
-d:删除分区硬盘分区表信息
-l:列出分区
--type YTPE:指定分区类型
--nr M-N:指定分区范围
选项:1
2
3-t TYPE:指定穿件的文件系统类型
-v:显示版本信息
-c:创建文件系统之前,先检查分区是否存在坏块
选项:1
2-c:创建交换分区之前,先检查分区是否存在坏块
-f:强制执行
mount [-fnrsvw] [-t vfstype] [-o options] device dir
选项: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-t vsftype:指定要挂载的设备上的文件系统类型
-r :readonly,只读挂载
-w:read and write,读写挂载
-n:不更新/etc/fstab
-a:自动挂载所有支持自动挂载的设备(定义在了/etc/fstab文件中,且挂载选项中有“自动挂载”功能)
-L 'LABEL':以卷标指定挂载设备
-U 'UUID':以UUID指定要挂载的设备
-B,--bind:绑定目录到另一个目录上
-o options:挂载文件系统的选项
async:异步模式
sync:同步模式
atime/noatime:包含目录和文件
diratime/nodiratime:目录的访问时间戳
auto/noauto:是否支持自动挂载
exec/noexec:是否支持将文件系统上的应用程序运行为进程
dev/nodev:是否支持在此文件系统上使用设备
suid/nosuid;
remount:重新挂载
ro:只读挂载
rw:读写挂载
user/nouser:是否允许普通用户挂载此设备
acl:启用此文件系统上acl功能
defaults:rw,suid,dev,exec,auto,nouser,and async
umount [-dflnrv] {dir|device}…
选项:1
2
3
4
5
6
7-a:卸除/etc/mtab中记录的所有文件系统;
-h:显示帮助;
-n:卸除时不要将信息存入/etc/mtab文件中;
-r:若无法成功卸除,则尝试以只读的方式重新挂入文件系统;
-t<文件系统类型>:仅卸除选项中所指定的文件系统;
-v:执行时显示详细的信息;
-V:显示版本信息。
swapon [-f] [-p priority] [-v] specialfile…
选项:1
2-a :激活所有的交换分区
-p PRIORITY:指定优先级
swapoff [-v] specialfile…
选项:1
-a:禁用所有的交换分区
查看硬盘以及分区情况
1 | [root@sg-pc /]# lsblk |
使用fdisk对/dev/sdb硬盘划分分区,划分3个主分区,每个主分区5G大小,并且划分一个扩展分区,4G大小。
1 | [root@sg-pc /]# fdisk /dev/sdb |
将新划分的分区加载到硬盘分区表中,并查看分区状态
1 | [root@sg-pc /]# partx -a /dev/sdb |
为分区创建文件系统,这边就选择/dev/sdb1分区作为示例
1 | [root@sg-pc /]# mkfs -t ext4 -L 'backup' /dev/sdb1 |
通过blkid命令,可以查看硬盘设备的信息
1 | [root@sg-pc /]# blkid |
将创建完文件系统的分区挂载指定目录下
1 | [root@sg-pc /]# mkdir /backup |
检查分区挂载情况
可以看到/dev/sdb1已经被挂载到/backup目录下了。
交换分区的创建与挂载步骤与普通分区一致,也是先划分分区,然后在分区上创建文件系统,接着是激活交换分区。因为交换分区与普通分区有一点不同,需要先调整分区的分区ID。
将/dev/sdb2分区作为交换分区,首先需要修改/dev/sdb2分区的分区ID
1 | [root@sg-pc /]# fdisk /dev/sdb |
创建交换分区的文件系统
1 | [root@sg-pc /]# mkswap -L 'myswap' /dev/sdb2 |
激活交换分区
1 | [root@sg-pc /]# free -m |
上述的硬盘的分区都是在系统中临时挂载使用的,当系统重启的话,目前我们挂载的分区并不会自动挂载上去,又需要我们执行挂载的步骤,这样很不方便。如果我们需要硬盘分区在系统重启的时候也能自动挂载,我们需要将分区的配置写到/etc/fstab这个文件中。
/etc/fstab文件中每一行代表一个启动的时候需要自动挂载的硬盘分区。
每一行记录友6个字段组成,按照顺序分别为:
我们以上面划分的./dev/sdb1分区为例,将其设置为每次机器重启的时候都会将/dev/sdb1分区挂载到相应的挂载点。
在/etc/fstab文件中添加如图所示的一行,表示每次机器重启的时候,都会将/dev/sdb1分区挂载到/backup挂载点上,并且该分区的文件系统类型为ext4类型,挂载选项是defautls,不备份,不自检。
总的来说,Linux下的硬盘分区以及挂载主要是三个步骤:
博客地址:https://win-man.github.io/
公众号:欢迎关注
使用Xtrabackup备份从库数据
1 | 备份从库 |
清空从库数据,并使用备份恢复从库
1 | [root@host-192-168-1-132 mysqldata1]# innobackupex --defaults-file=/etc/my.cnf --copy-back /tmp/backup/ |
查看xtrabckup中备份的slave信息
1 | [root@host-192-168-1-132 backup]# cat xtrabackup_slave_info |
启动从库,查看从库信息
1 | [root@host-192-168-1-132 mysqldata1]# service mysqld start |
start slave的时候出现错误,于是重置了slave信息,重新change master 解决问题
1 | mysql> reset slave all; |
博客地址:https://win-man.github.io/
公众号:欢迎关注
在《高性能MySQL》上看到说在一主多从的架构中,如果从库的sever_id设置为一样的,可能会导致一些奇怪的现象,例如从库的错误日志中会不断的打印错误日志,会不断的断开连接并重新连接。
在主库上,会发现两台备库只有一台连接到主库(通常情况下所有的备库都会建立连接等待随时进行复制)。在备库的错误日志中,则会发现反复的重连和连接断开信息,但不会提及被错误配置的服务器ID。
根据眼见为实,耳听为虚的原则,我搭了一套一主两从的环境,将两台从库的server_id设置为了一样的。但是并没有看到书上提到的现象。考虑了一下,会不会是数据库版本的原因,因为我的测试的数据库版本是5.7.18版本的。于是又重新搭建了一套5.5.36版本的数据库,并成功复现了书上所讲的现象。
下面是我的测试步骤。
三台主机除server_id之外,其余配置如下: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
31server_id = 123
[client]
socket = /home/mysql/data/mysqldata5.5/sock/mysql.sock
[mysqld]
#server_id = 3655
server_id = 123
port = 3306
skip_name_resolve = 1
binlog_format = ROW
#binlog_format = STATEMENT
basedir = /home/mysql/program/mysql5.5.36
datadir = /home/mysql/data/mysqldata5.5/mydata
socket = /home/mysql/data/mysqldata5.5/sock/mysql.sock
pid-file = /home/mysql/data/mysqldata5.5/sock/mysql.pid
tmpdir = /home/mysql/data/mysqldata5.5/tmpdir
log-error = /home/mysql/data/mysqldata5.5/log/error.log
slow_query_log
slow_query_log_file = /home/mysql/data/mysqldata5.5/slowlog/slow-query.log
log-bin = /home/mysql/data/mysqldata5.5/binlog/mysql-bin
relay-log = /home/mysql/data/mysqldata5.5/relaylog/mysql-relay-bin
innodb_data_home_dir = /home/mysql/data/mysqldata5.5/innodb_ts
innodb_log_group_home_dir = /home/mysql/data/mysqldata5.5/innodb_log
#innodb_undo_directory = /home/mysql/data/mysqldata5.5/undo/
sync_binlog=1
innodb_file_per_table=1
#skip_grant_tables
expire_logs_days = 1
log_slave_updates = ON
#replicate-same-server-id=1
skip_slave_start
#innodb_undo_tablespaces=1
初始搭建环境之后,查看各主机状态。搭建环境的步骤就省略。
主库通过show processlist语句查看,只有一个dump线程,但是通过多次刷新,可以看到连接的是不同的服务器。可以看到每次通过show processlist语句显示的dump线程的Host字段中,IP:PORT的值是不断在更新的,说明dump线程在不断的重连,才会出现占用不同的端口的现象。
通过show slave status\G
命令查看复制状态,多次执行可以看到Slave_IO_Running
字段显示的内容,出现YES或者Connnecting两种状态。可以看到I/O线程在不断的进行重连。
并且通过tail -f
命令查看error log,可以看到I/O线程一直在尝试重新连接。
可以看到在错误日志中打印的信息是,I/O线程连接
从库B现象与从库A一致。
搭建环境步骤省略。
show processlist查看有两个dump线程,并且多次刷新,发现Host字段中的IP:PORT并没有修改,说明dump线程一直保持连接。
tail -f /home/mysql/data/mysqldata5.6/log/error.log查看错误日志,没有不断断开连接
tail -f /home/mysql/data/mysqldata5.6/log/error.log查看错误日志,没有不断断开连接
http://www.penglixun.com/tech/database/mysql_multi_slave_same_serverid.html这是彭大大写的关于多个slave使用相同server_id时冲突的原因。按照彭大大的分析,我理解的是,slave的I/O线程连接上主库的时候,主库上会调用register_slave()
这个函数,在这个函数中又调用了unregister_slave()函数,会将之前使用相同server_id的线程给注销掉。从而导致从库的I/O线程不断断开重连。
但是仔细看了一下unregister_slave()函数的代码,并没有发现MySQL是根据server_id来注销dump线程的。并且进一步比较了一下5.5.36和5.6.36版本的代码,并没有发现不同。
进一步看了一下彭大大的文章,发现有人在下面评论,说主要是kill_zombie_slave_threads()
函数导致的。于是看了一下kill_zombie_slave_threads()
函数的逻辑,发现MySQL应该就是在这一步根据server_id将线程kill了。
5.5.36版本
首先来看下5.5.36版本的kill_zombie_dump_threads()
函数的代码。看到这个函数传入的参数是一个uint32类型的slave_server_id,在函数中做的事情是,遍历MySQL中的所有线程,如果遍历到一个线程是dump线程并且线程的server_id是等于传入的参数值话,则跳出遍历循环,并对kill掉这个线程。
1 | void kill_zombie_dump_threads(uint32 slave_server_id) |
5.6.35版本
再来看一下5.6.36版本的kill_zombie_dump_threads()
函数的代码实现,与5.5.36大不相同。首先传入的参数是一THD类型的指针,在函数中实现的逻辑同样是遍历MySQL中的所有线程,如果找到dump线程,首先看一下这个线程有没有uuid字段(因为uuid是在5.6之后的版本才有的,这边是为了兼容5.5),如果有uuid则用uuid进行比较,如果没有uuid,则用server_id进行比较。
1 | void kill_zombie_dump_threads(THD *thd) |
函数调用
知道了kill_zombie_dump_threads()
线程实现的逻辑,那MySQL是在什么地方会调用这个函数的呢。看了一下函数是在case COM_BINLOG_DUMP
中被调用的。
在5.5.36版本中是在
1 | case COM_BINLOG_DUMP: |
在5.6.36版本中也是在case COM_BINLOG_DUMP
中,只不过是将之前的逻辑封装在了com_binlog_dump()
函数中了,kill_zombie_dump_threads()
也是在com_binlog_dump()
函数中调用的。1
2
3case COM_BINLOG_DUMP:
error= com_binlog_dump(thd, packet, packet_length);
break;
case COM_BINLOG_DUMP
中所进行的操作就是将dump线程通知I/O线程拉取新的binlog。
整理下来的话,基本上可以确定主要是因为kill_zombie_dump_threads()
函数导致在5.6之前的版本中,如果是一主多从的架构中,如果在从库之间的server_id如果设置为一样,会出现从开I/O线程不断断开重连的现象。因为在5.6之前的版本中,还没有UUID的概念,MySQL使用server_id来区分是否是同一台机器,而在5.6之后的版本是使用的UUID来区分。
总结一句,就是数据库之间的server_id不要设置成一样,不然可能会有一些不可预知的错误。
博客地址:https://win-man.github.io/
公众号:欢迎关注
其实这篇年终总结早就想写了,可是拖延症犯了,一直拖啊拖啊,已经拖过了 2016 与 2017 年的交界,可是作为一名中国人,我为什么一定要以公历年份来划分我的时间呢,我选择猴年与鸡年来划分我的时间。所以,这篇总结不算晚。
过去的一年,由我大三下与大四上组成。从一开始就没有考研的打算,实习便成为了我的一年的主要内容。
第一段实习经历是在实验室老师成立的公司,做了一段时间的 Java 开发,之后选择了换一家公司。原因总结来说的话,就是看不到未来,那时候还有一点技术改变世界的想法,感觉做出来的产品完全称不上是一个产品,简直就是学校里一个课程设计。老板出去还把这产品吹的天花乱坠的,实际上完全是另一回事。所以果断弃坑。
第二段实习经历,主要是为了完成学院的实习要求,还是做 Java 开发。中间过程没有一点可言的。不过也要感谢这段实习经历,让我有时间静下来,学一些东西。也就是在这个期间,我将我的博客从 CSDN 转到了 GitHub,加入了 itsCoder ······ 让我有时间去做我想做的事情了。最后完成学院要求之后,还是毅然决然的离开了,因为不明白,为什么一个成立时间不到两年的一个公司,整天的气氛是死气沉沉的,没有技术氛围。
第三段实习经历,就是目前正在经历着的。结束上一段实习经历的时候,我就打算这次好好找一个实习,奔着毕业之后转正的目的找的。投了一波简历,面了一波试。在最后选择了现在的公司,并且完成了转型,从开发转行成为了一名 DBA 。到目前为止,我想我应该是找到了我想要的工作。
学习这方面的话,整体上进度是不大的。花了前面大半年的时间,都是在学习开发方面的内容,学框架,学技术,学算法,最后怎么也没想到直接从开发转行了,所以学的很多东西对于工作来说,意义不大了。转行 DBA,开始接触数据库开始,才发现原来数据库水这么深,之前理解的数据库就是一个数据的增删改查,之后发现这就是一个新的世界。
过去的一年,算是崩坏的一年。
身体没有好好锻炼,锻炼一段时间歇一段时间的;
书没好好读,好多书都是走马观花的浏览了一遍,也没看到心里去;
习惯没有好好养成,有很多习惯想要养成,现在看来一个也没成功;
计划没有好好执行,计划任然是计划。
一年时间,体重飙涨20斤,还好及时发现,狠命锻炼一段时间,减到 70KG ,目前仍维持着。
自控力下降,执行力降低。
上一张 Github 2016 年的记录,最难做到的还是坚持:
一句话总结我过去的猴年:瞎搞。
本来一开始想去大公司开始实习的,准备准备,干一波春招。结果被老师打乱了节奏,三段实习经历,公司都不大,但也发现了小公司的好处。自由。不打卡,可以有自己的话语权,公司同事整体年龄比较年轻,有活力。
一年下来,没有多少收获,只是找到了之后的职业方向,对自己职业也有了初步的规划。我觉得有这一点也已经够了。
又到了制定计划的时候了,把话撂在这,等着明年来打脸(注定的:
博客地址:https://win-man.github.io/
公众号:欢迎关注
之前讲了如何安装 Tmux,这篇文章讲讲如何使用 Tmux。其实工具的使用都是很简单,最终是看你如何使用这个工具,才能发挥出工具最大的作用。
在讲如何使用 Tmux 之前,我们需要先熟悉它的几个概念。
会话:会话的概念很好理解。我们一台服务器正在那边运行着,我们拿终端工具如:XShell、SecureCRT 等去连接的时候,每新建一个连接,就是一个新的会话。使用 Tmux 新建会话的时候,也是一样,一个新的会话就表示一个新的连接。
窗口:窗口的概念,可以类比于 Windows 里面的窗口的概念。之前我们连服务器的时候,终端工具每次连接只有一个界面,当我们需要同时操作多个过程的时候,我们就需要建立新的连接。这样很不方便。Tmux 里面的窗口的概念,就可以让我们在一个会话里有多个界面,就不需要去建立的一个会话。
面板:面板的概念的话,是用于对界面的布局而言的。就是将一个界面划分为多个不同的区域,每个区域我们称之为一个面板。
简单来说就是,一个会话里面可以有多个窗口,一个窗口里面可以有多个面板。
Tmux 可以有两种使用方式,一种是命令行的方式,一种是快捷键的方式。前者的话不需要怎么记忆,后者的话效率更高。我觉得还是命令行入门,先熟悉这个工具的作用,之后将常用的几个功能的快捷键记下来,多使用,多熟练。
1 | $ tmux new -s [session_name] // 创建一个会话 |
创建完会话之后,会自动进入这个会话之内。并且会话默认帮你创建好一个窗口。
1 | $ tmux list-sessions // 显示所有会话,也可以简写成 tmux ls |
当前的话,我一共有一个会话,并且会话的名称为: session1 。
1 | $ tmux detach // 退出当前的会话,返回 shell 界面 |
讲完会话的操作,我们来讲讲窗口的操作。1
$ tmux new-window [-n window_name] // 创建一个新的窗口,可以指定新的窗口的名字也可以不指定
这边,我新建了一个名为 window1 的窗口,并且 Tmux 自动帮我切换到了这个窗口,*
标记当前正在使用的窗口,一个窗口默认包含一个面板。
1 | $ tmux rename-window [new_window_name] // 重命名当前窗口的名字 |
1 | $ tmux list-windows // 显示当前会话中所有的窗口 |
1 | $ tmux kill-window -t [window_name | window_index] // 关闭一个窗口 |
1 | $ tmux split-window //将一个面板垂直切成两个面板 |
可以看到图片中的话,我将一个窗口切成了三部分区域,每一个区域都是一个面板。
1 | $ tmux swap-pane -[UDRL] // 选择 [ 上下左右 ] 的面板交换 |
以上的话就是同过命令行的方式使用 Tmux,使用命令行的方式,可以简单了解一下 Tmux 这个工具提供的一些功能。接下来就是进阶的,使用快捷键的方式操作 Tmux。
Tmux 快捷键的话需要先按下前缀键,之后再按快捷键才会有效果。 Tmux 默认的前缀键是 Ctrl + b
。我就只简单罗列一下快捷键,实际效果的话,使用一下就知道了,上面使用命令行能达到的功能,都能找到相应的快捷键。
Tmux 还有一个配置文件,可以根据自己的习惯将快捷键改成自己喜欢的键。
1 | ? 列出所有快捷键;按q返回 |
1 | c 创建新窗口 |
1 | " 将当前面板上下分屏 |
说到底 Tmux 也就是这么一个工具,功能也就这么多,但是将 Tmux 和 Vim 结合起来的时候,效果就不一样了,在命令行下开发,整个逼格一下就上去了。装逼使人进步。
博客地址:https://win-man.github.io/
公众号:欢迎关注
Linux 命令行装逼利器——Tmux。转行 DBA 之后整天和命令行打交道,在装逼的道路上越走越远了。Tmux 是 Linux 命令行下一个工具,让我可以更加方便的装逼。先讲一下怎么安装这个工具,之后再写一篇文章记录一下怎么使用这个工具。
系统环境:
CentOS 6.5
tmux
工具依赖于 libevent
和 ncurses
两个软件包。我们先安装这两个软件包。
1 | // 下载 tar.gz 文件 |
1 | $ yum install ncurses-devel |
1 | // 下载 tar.gz 文件 在 https://tmux.github.io/ 可以下载到最新版 |
在 /etc/profile 最末尾增加 PATH=$PATH:/usr/local/tmux/bin
,并使用 source
命令生效。
1 | // 将 tmux 拷贝到环境变量目录下 |
运行 tmux
命令提示 libevent-2.0.so.5
找不到。
解决方案:1
2// 将 libevent-2.0.so.5 移动到 /usr/lib64 下(64位操作系统) | /usr/lib 下(32位操作系统)
$ cp /usr/local/libevent/lib/libevent-2.0.so.5 /usr/lib64
博客地址:https://win-man.github.io/
公众号:欢迎关注