MySQL数据库企业级应用实践(多实例源码编译)

MySQL数据库企业级应用实践(多实例源码编译)

链接:https://pan.baidu.com/s/1ANGg3Kd_28BzQrA5ya17fQ
提取码:ekpy
复制这段内容后打开百度网盘手机App,操作更方便哦

image_1ckrrgecridsmub1s29cb9eb49.png-63.3kB

1.MySQL多实例的简介

  • 简单的说,MySQL多实例就是在一台服务器上同时开启多个不同的服务器端口(如:3306,3307),同时运行多个MySQL服务进程,这些服务进程通过不同的socket监听不同的服务器端口来提供服务。
  • 这些MySQL多实例共用一套MySQL安装程序,使用不同的my.cnf(也可以相同)配置文件,启动程序(也可以相同)和数据文件。在提供服务时,多实例MySQL在逻辑上看起来是各自独立的,它们根据配置文件的对应设定值,获得服务器相应数量的硬件资源。
  • 打个比方吧,MySQL多实例就相当于房子的多个卧室,每个实例可以看作一间卧室,整个服务器就是一套房子,服务器的硬件资源(CPU,Mem,Disk),软件资源(Centos操作系统)可以看作房子的卫生间,厨房,客厅,是房子的公用资源。
  • 其实很多网络服务都是可以配置多实例的,例如Nginx,Apache,Haproxy,Redis,Memcache等。这在门户网站使用得很广泛。

2.MySQL多实例的作用

2.1有效利用服务器资源

当单个服务器资源有剩余时,可以充分利用剩余的资源提供更多的服务,且可以实现资源的逻辑隔离。

2.2节约服务器资源

当公司资金紧张,但是数据库又需要各自尽量独立地提供服务,而且,需要主从复制等技术时,多实例就再好不过了。

image_1ckrri9pd1pp7ah1nu5llb6ej4m.png-634.4kB

2.3MySQL多实例有它的好处,但也有其弊端,比如:会存在资源互相抢占的问题。

当某个数据库实例并发很高或有SQL慢查询时,整个实例会消耗大量的系统CPU,磁盘I/O等资源,导致服务器上的其他数据库实例提供服务的质量一起下降。这就相当于大家住在一个房子的不同卧室一样,早晨起来上班,都要刷牙,洗脸等,这样卫生间就会长期占用,其他人要等待一样。不同实例获取的资源是相对独立的,无法像虚拟化一样完全隔离。

3.安装并配置多实例MySQL数据库

3.1安装MySQL需要的依赖包和编译软件

[root@yangwenbo /]# yum -y install gcc gcc-c++ cmake ncurses-devel libaio-devel
[root@yangwenbo /]# rpm -qa gcc gcc-c++ cmake ncurses-devel libaio-devel
gcc-c++-4.4.7-4.el6.x86_64
cmake-2.6.4-5.el6.x86_64
gcc-4.4.7-4.el6.x86_64
libaio-devel-0.3.107-10.el6.x86_64
ncurses-devel-5.7-3.20090208.el6.x86_64

3.2安装编译cmake(源码包)

[root@yangwenbo yang]# ls
cmake-2.8.6.tar.gz  mysql-5.5.22.tar.gz

3.2.1解包

[root@yangwenbo yang]# tar xf cmake-2.8.6.tar.gz -C /usr/src/
[root@yangwenbo yang]# cd /usr/src/cmake-2.8.6/
[root@yangwenbo cmake-2.8.6]# ls
bootstrap                   CMakeLists.txt            CTestCustom.cmake.in  Modules
ChangeLog.manual            CMakeLogo.gif             CTestCustom.ctest.in  Readme.txt
ChangeLog.txt               cmake_uninstall.cmake.in  DartConfig.cmake      Source
cmake.1                     CompileFlags.cmake        DartLocal.conf.in     Templates
CMakeCPack.cmake            configure                 Docs                  Tests
CMakeCPackOptions.cmake.in  Copyright.txt             doxygen.config        Utilities
CMakeGraphVizOptions.cmake  CTestConfig.cmake         Example

3.2.2编译安装

[root@yangwenbo cmake-2.8.6]# ./configure && gmake && gmake install

3.3开始安装MySQL(源码包)

3.3.1安装MySQL程序用户

[root@yangwenbo yang]# useradd -s /sbin/nologin -M mysql
[root@yangwenbo yang]# id mysql
uid=500(mysql) gid=500(mysql) groups=500(mysql)

3.3.2解包

[root@yangwenbo yang]# tar xf mysql-5.5.22.tar.gz -C /usr/src/
[root@yangwenbo yang]# cd /usr/src/mysql-5.5.22/
[root@yangwenbo mysql-5.5.22]# ls
BUILD           configure.cmake  INSTALL-WIN-SOURCE  packaging  sql-common     vio
BUILD-CMAKE     COPYING          libmysql            plugin     storage        win
client          dbug             libmysqld           README     strings        zlib
cmake           Docs             libservices         regex      support-files
CMakeLists.txt  extra            man                 scripts    tests
cmd-line-utils  include          mysql-test          sql        unittest
config.h.cmake  INSTALL-SOURCE   mysys               sql-bench  VERSION

3.3.3编译安装

[root@yangwenbo mysql-5.5.22]#cmake . -DCMAKE_INSTALL_PREFIX=/usr/local/mysql-5.5.22 
-DMYSQL_DATADIR=/usr/local/mysql-5.5.22/data#数据存放目录
-DMYSQL_UNIX_ADDR=/usr/local/mysql-5.5.22/tmp/mysql.sock#MySQL进程间通信的套接字位置
-DDEFAULT_CHARSET=utf8#默认字符集为utf8
-DDEFAULT_COLLATION=utf8_general_ci#默认字符集排序规则
-DEXTRA_CHARSETS=gbk,gb2312,utf8,ascii#额外的字符集支持
-DENABLED_LOCAL_INFILE=ON#是否启用加载本地数据
-DWITH_INNOBASE_STORAGE_ENGINE=1#静态编译innodb存储引擎到数据库
-DWITH_FEDERATED_STORAGE_ENGINE=1#静态编译FEDERATED存储引擎到数据库
-DWITH_BLACKHOLE_STORAGE_ENGINE=1#静态编译blackhole存储引擎到数据库
-DWITHOUT_EXAMPLE_STORAGE_ENGINE=1#不编译EXAMPLE存储引擎到数据库
-DWITHOUT_PARTITION_STORAGE_ENGINE=1#不支持数据库分区
-DWITH_FAST_MUTEXES=1 
-DWITH_ZLIB=bundled#zlib压缩模式
-DENABLED_LOCAL_INFILE=1#是否启用本地的LOCAL_INFILE
-DWITH_READLINE=1#使用捆绑的readline
-DWITH_EMBEDDED_SERVER=1#是否要建立嵌入式服务器
-DWITH_DEBUG=0#禁用DEBUG(开启影响性能)
&& make && make install

3.3.4设置不带版本号的软链接/usr/local/mysql,操作步骤如下:

[root@yangwenbo mysql-5.5.22]# ln -s /usr/local/mysql-5.5.22 /usr/local/mysql
[root@yangwenbo mysql-5.5.22]# ls /usr/local/mysql
bin  COPYING  data  docs  include  INSTALL-BINARY  lib  man  mysql-test  README  scripts  share  sql-bench  support-files

3.3.5创建MySQL多实例的数据文件目录

[root@yangwenbo /]# mkdir -p /data/{3306,3307}/data
[root@yangwenbo /]# tree /data/
/data/
├── 3306        #3306实例目录
│   └── data    #3306实例的数据文件目录
└── 3307        #3307实例目录
    └── data    #3307实例的数据文件目录

4 directories, 0 files

提示:如果是创建多个目录,可以增加如3308,3309这样的目录名,在生产环境中,一般为3~4个实例为佳。

3.3.6创建MySQL多实例的配置文件

MySQL数据库默认为用户提供了多个配置文件模板,用户可以根据服务器硬件配置的大小来选择。

[root@yangwenbo local]# cd /usr/local/mysql
[root@yangwenbo mysql]# ls -l support-files/my*.cnf
-rw-r--r--. 1 root root  4751 Aug 15 03:02 support-files/my-huge.cnf
-rw-r--r--. 1 root root 19805 Aug 15 03:02 support-files/my-innodb-heavy-4G.cnf
-rw-r--r--. 1 root root  4725 Aug 15 03:02 support-files/my-large.cnf
-rw-r--r--. 1 root root  4736 Aug 15 03:02 support-files/my-medium.cnf
-rw-r--r--. 1 root root  2900 Aug 15 03:02 support-files/my-small.cnf

3.3.7上面是单实例的默认配置文件模板,如果配置多实例,和单实例会有不同。为了让MySQL多实例之间彼此独立,要为每一个实例建立一个my.cnf配置文件和一个启动文件MySQL,让他们分别对应自己的数据文件目录data。首先,通过vim命令添加配置文件内容,命令如下:

[root@yangwenbo /]# vim /data/3306/my.cnf
[root@yangwenbo /]# vim /data/3307/my.cnf
[client]
port        = 3307   #3306实例的启动文件只需修改3307启动文件的端口即可
socket      = /data/3307/mysql.sock
[mysqld]
user        = mysql
port        = 3307
socket      = /data/3307/mysql.sock
basedir     = /usr/local/mysql
datadir     = /data/3307/data
open_files_limit    = 1024
back_log = 600
max_connections = 800
max_connect_errors = 3000
table_open_cache = 614
external-locking = FALSE
max_allowed_packet = 8M
#binlog_cache_size = 1M
#max_heap_table_size = 64M
#read_buffer_size = 2M
#read_rnd_buffer_size = 16M
sort_buffer_size = 1M
join_buffer_size = 1M
thread_cache_size = 100
thread_concurrency = 2
query_cache_size = 2M
query_cache_limit = 1M
query_cache_min_res_unit = 2k
#ft_min_word_len = 4
#default-storage-engine = MYISAM
thread_stack = 192K
transaction_isolation = READ-COMMITTED
tmp_table_size = 2M
max_heap_table_size = 2M
#log-bin=mysql-bin
#binlog_format=mixed
#slow_query_log
long_query_time = 1
pid-file = /data/3307/mysql.pid
relay-log = /data/3307/relay-bin
relay-log-info-file = /data/3307/relay-log.info
binlog_cache_size = 1M
max_binlog_cache_size = 1M
max_binlog_size = 2M
key_buffer_size = 16M
read_buffer_size = 1M
read_rnd_buffer_size = 1M
bulk_insert_buffer_size = 1M
lower_case_table_names = 1
skip-name-resolve
slave-skip-errors = 1032,1062
replicate-ignore-db = mysql
server-id = 1
#key_buffer_size = 32M
#bulk_insert_buffer_size = 64M
#myisam_sort_buffer_size = 128M
#myisam_max_sort_file_size = 10G
#myisam_repair_threads = 1
#myisam_recover
innodb_additional_mem_pool_size = 4M
innodb_buffer_pool_size = 32M
innodb_data_file_path = ibdata1:128M:autoextend
innodb_file_io_threads = 4
#innodb_write_io_threads = 8
#innodb_read_io_threads = 8
innodb_thread_concurrency = 8
innodb_flush_log_at_trx_commit = 2
innodb_log_buffer_size = 2M
innodb_log_file_size = 4M
innodb_log_files_in_group = 3
innodb_max_dirty_pages_pct = 90
innodb_lock_wait_timeout = 120
innodb_file_per_table = 0
[mysqldump]
quick
max_allowed_packet = 2M
[mysql]
no-auto-rehash
#[myisamchk]
#key_buffer_size = 512M
#sort_buffer_size = 512M
#read_buffer = 8M
#write_buffer = 8M
#[mysqlhotcopy]
#interactive-timeout
[mysqld_safe]
log-error = /data/3307/mysql_yunjisuan3307.err
pid-file = /data/3307/mysqld.pid

3.3.8最终完成后的多实例根/data目录结果如下:

[root@yangwenbo /]# tree /data
/data
├── 3306
│   ├── data
│   └── my.cnf       #这个就是3306实例的配置文件
└── 3307
    ├── data
    └── my.cnf       #这个就是3307实例的配置文件

4 directories, 2 files

3.3.9创建MySQL多实例的启动文件

[root@yangwenbo 3307]# vim /data/3306/mysql
[root@yangwenbo 3307]# vim /data/3307/mysql
[root@yangwenbo 3307]# cat /data/3307/mysql
#!/bin/bash
###############################################

port=3307     #3306实例的启动文件只需修改3307启动文件的端口即可
mysql_user="root"
mysql_pwd="971108"            #这里需要修改为用户的实际密码

CmdPath="/usr/local/mysql/bin"
mysql_sock="/data/${port}/mysql.sock"

#startup function
function_start_mysql(){

    if [ ! -e "$mysql_sock" ];then
		printf "Starting MySQL....\n"
		/bin/sh ${CmdPath}/mysqld_safe --defaults-file=/data/${port}/my.cnf 2>&1 >/dev/null &
    else
        printf "MySQL is running...\n"
        exit
    fi
}

#stop function
function_stop_mysql(){

    if [ ! -e "$mysql_sock" ];then
		printf "MySQL is stopped...\n"
		exit
	else
		printf "Stoping MySQL...\n"
		${CmdPath}/mysqladmin -u ${mysql_user} -p${mysql_pwd} -S /data/${port}/mysql.sock shutdown
    fi
}

#restart function
function_restart_mysql(){

    printf "Restarting MySQL...\n"
    function_stop_mysql
    sleep 2
    function_start_mysql
}

case $1 in 
start)
	function_start_mysql
;;
stop)
	function_stop_mysql
;;
restart)
	function_restart_mysql
;;
*)
	printf "Usage: /data/${port}/mysql{start|stop|restart}\n"
esac

3.3.10最终完成后的多实例根/data目录结果如下:

[root@yangwenbo /]# tree /data
/data
├── 3306
│   ├── data           #3306实例的配置文件
│   └── mysql          #3306实例的启动文件
└── 3307
    ├── data           #3307实例的配置文件
    └── mysql          #3307实例的启动文件

4 directories, 2 files

3.4配置MySQL多实例的文件权限

3.4.1通过以下的命令,授权mysql用户和组管理整个多实例的根目录/data

[root@yangwenbo ~]# chown -R mysql.mysql /data
[root@yangwenbo ~]# find /data -name "mysql" | xargs ls -l
-rw-r--r--. 1 mysql mysql 1077 Aug 15 21:54 /data/3306/mysql
-rw-r--r--. 1 mysql mysql 1077 Aug 15 22:00 /data/3307/mysql

3.4.2通过以下的命令,授权MySQL多实例所有启动文件的mysql可执行,设置700权限最佳(注意不要用755权限,因为启动文件里有数据库管理员密码,会被读取到)

[root@yangwenbo ~]# find /data -name "mysql" | xargs chmod 700
[root@yangwenbo ~]# find /data -name "mysql" | xargs ls -l
-rwx------. 1 mysql mysql 1077 Aug 15 21:54 /data/3306/mysql
-rwx------. 1 mysql mysql 1077 Aug 15 22:00 /data/3307/mysql

3.5 MySQL相关命令加入全局路径的配置

3.5.1配置全局路径的意义

如果不为MySQL的命令配置全局路径,就无法直接在命令行输入mysql这样的命令,只能用全路径命令(/usr/local/mysql/bin/mysql),这种带着路径输入命令的方式很麻烦。

3.5.2配置MySQL全局路径的方法

(1)确认mysql命令所在路径,命令如下:

[root@yangwenbo ~]# ls /usr/local/mysql/bin/mysql
/usr/local/mysql/bin/mysql

(2)在PATH变量前面增加/usr/local/mysql/bin路径,并追加到/etc/profile文件中,命令如下:

[root@yangwenbo ~]# echo 'export PATH=/usr/local/mysql/bin:$PATH' >> /etc/profile  
#注意,echo后边是单引号,双引号的话变量内容会被解析掉。
[root@yangwenbo ~]# tail -1 /etc/profile
export PATH=/usr/local/mysql/bin:$PATH
[root@yangwenbo ~]# source /etc/profile
#执行source使上一行添加到/etc/profile中,内容直接生效
#以上命令的用途为定义mysql全局路径,实现在任意路径执行mysql命令

提示:更简单的设置方法为用下面命令做软链接:

[root@yangwenbo ~]# ln -s /usr/local/mysql/bin/* /usr/local/sbin/

把mysql命令说在路径链接到全局路径/usr/local/sbin/的下面。

3.6初始化MySQL多实例的数据库文件

3.6.1初始化MySQL数据库,命令如下:

[root@yangwenbo scripts]# pwd
/usr/local/mysql-5.5.22/scripts
[root@yangwenbo scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3306/data --user=mysql
[root@yangwenbo scripts]# ./mysql_install_db --basedir=/usr/local/mysql --datadir=/data/3307/data --user=mysql

提示:--basedir=/usr/local/mysql为MySQL的安装路径,--datadir为不同的实例数据目录

3.6.2初始化数据库的原理及结果说明

  • 初始化数据库的实质就是创建基础的数据库系统的库文件,例如:生成MySQL库表等。
  • 初始化数据库后查看对应实例的数据目录,可以看到多了如下文件:
[root@yangwenbo scripts]# tree /data

#以下省略若干...

3.7启动MySQL多实例的命令

[root@yangwenbo scripts]# /data/3306/mysql start
Starting MySQL....
[root@yangwenbo scripts]# /data/3307/mysql start
Starting MySQL....
[root@yangwenbo scripts]# netstat -antup | grep 330
tcp        0      0 0.0.0.0:3307            0.0.0.0:*                   LISTEN      2672/mysqld         
tcp        0      0 0.0.0.0:3306            0.0.0.0:*                   LISTEN      1957/mysqld

需要特别说明一下,在多实例启动文件中,启动MySQL不同实例服务,所执行的命令实质是有区别的,例如,

  • 启动3306实例的命令如下:
    mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 >/dev/null
  • 启动3307实例的命令如下:
    mysqld_safe --defaults-file=/data/3307/my.cnf 2>&1 >/dev/null
  • 下面看看在多实例启动文件中,停止MySQL不同实例服务的实质命令。
  • 停止3306实例的命令如下:
    mysqladmin -uroot -pyunjisuan123 -S /data/3306/mysql.sock shutdown
  • 停止3307实例的命令如下:
    mysqladmin -u root -pyunjisuan123 -S /data/3307/mysql.sock shutdown
    从输出中可以看到,3306和3307实例均已正常启动。

3.8配置及管理MySQL多实例数据库

3.8.1配置MySQL多实例数据库开机自启动

[root@yangwenbo scripts]# echo "#mysql multi instances" >> /etc/rc.local
[root@yangwenbo scripts]# echo "/data/3306/mysql start" >> /etc/rc.local
[root@yangwenbo scripts]# echo "/data/3307/mysql start" >> /etc/rc.local
[root@yangwenbo scripts]# tail -3 /etc/rc.local
#mysql multi instances
/data/3306/mysql start
/data/3307/mysql start

3.8.2登陆MySQL测试

[root@yangwenbo scripts]# mysql -S /data/3306/mysql.sock
#直接敲就进来了,而且身份还是root。但是多了-S /data/3306/mysql.sock,用于区别登陆不同的实例
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.5.22 Source distribution

Copyright (c) 2000, 2011, 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.

mysql> show databases;        #查看当前所有的数据库
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| test               |
+--------------------+
4 rows in set (0.00 sec)

mysql> select user();         #查看当前的登陆用户
+----------------+
| user()         |
+----------------+
| root@localhost |
+----------------+
1 row in set (0.00 sec)

3.8.3MySQL安全配置

[root@yangwenbo scripts]# mysqladmin -u root -S /data/3306/mysql.sock password '971108'            #为mysql设置密码
[root@yangwenbo scripts]# mysql -uroot -p -S /data/3306/mysql.sock
Enter password:     #无法直接登陆了
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 9
Server version: 5.5.22 Source distribution

Copyright (c) 2000, 2011, 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.

mysql> 

3307设密同上

3.8.4带密码登陆不同实例数据库的方法:

登陆3306(3307)实例的命令如下:

[root@yangwenbo scripts]# mysql -uroot -p971108 -S /data/3306/mysql.sock
[root@yangwenbo scripts]# mysql -uroot -p971108 -S /data/3307/mysql.sock

未解bug之谜,每次关机重启MySQL就必须输入以下命令(不可自启动,不可脚本)

mysqld_safe --defaults-file=/data/3306/my.cnf 2>&1 >/dev/null
mysqld_safe --defaults-file=/data/3307/my.cnf 2>&1 >/dev/null

3.8.5多实例MySQL登陆问题分析

  • 多实例本地登录MySQL

多实例本地登录一般通过socket文件来指定具体登陆到哪个实例,此文件的具体位置是在MySQL编译过程或my.cnf文件中指定的。在本地登陆数据库时,登陆程序会通过socket文件来判断登陆的是哪个数据库实例。
例如:通过mysql -uroot -p '123123' -S /data/3307/mysql.sock可知,登陆的是3307这个实例。
mysql.sock文件是MySQL服务器端与本地MySQL客户端进行通信的UNIX套接字文件。

  • 远程连接登陆MySQL多实例

远程登陆MySQL多实例中的一个实例时,通过TCP端口(port)来指定说要登陆的MySQL实例,此端口的配置是在MySQL配置文件my.cnf中指定的。
例如:在mysql -uyunjisuan -p '123123' -h 192.168.200.101 -P 3307中,-P为端口参数,后面接具体的实例端口,端口是一种“逻辑连接位置”,是客户端程序被分派到计算机上特殊服务程序的一种方式,强调提前在192.168.200.101上对yunjisuan用户做了授权。