Skip to content

Cmake MySQL5.7 Example

一. 环境准备

  • System:CentOS7 5.18.14-1.el7.elrepo.x86_64
  • MySQL:mysql-boost-5.7.39.tar.gz

1)卸载默认的 mariadb

1
2
3
4
5
6
7
# 确认是否有其它版本
$ rpm -qa mysql
$ rpm -qa | grep mariadb

# 删除相关的程序文件及依赖
$ rpm -qa | grep mariadb | xargs yum remove -y
$ rm -rf /etc/my.cnf /etc/my.cnf.d/

二. 编译安装

源码编译安装,详细可参考 官网

1)下载依赖包,并提前到 MySQL 官网 下载程序包(选择的是 mysql-boost 的包)

1
2
3
$ yum -y install ncurses-devel cmake libaio-devel openssl-devel gcc gcc-c++ bison
$ tar -xf mysql-boost-5.7.39.tar.gz
$ cd mysql-5.7.39

注:环境不一样,可能还需要安装其他依赖包,比如 perl 相关的包

2)创建 MySQL 用户和组

$ groupadd mysql
$ useradd -r -g mysql -s /sbin/nologin mysql

3)基于 cmake 进行配置,进行预编译

$ cmake . \
-DCMAKE_INSTALL_PREFIX=/opt/mysql \
-DMYSQL_DATADIR=/opt/mysql/data \
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \
-DSYSCONFDIR=/etc \
-DMYSQL_TCP_PORT=3306 \
-DWITH_INNOBASE_STORAGE_ENGINE=1 \
-DWITH_PARTITION_STORAGE_ENGINE=1 \
-DWITH_FEDERATED_STORAGE_ENGINE=1 \
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \
-DWITH_MYISAM_STORAGE_ENGINE=1 \
-DWITH_EMBEDDED_SERVER=1 \
-DENABLED_LOCAL_INFILE=1 \
-DEXTRA_CHARSETS=all \
-DDEFAULT_CHARSET=utf8mb4 \
-DDEFAULT_COLLATION=utf8mb4_general_ci \
-DWITH_SSL=system \
-DWITH_BOOST=boost

注:如编译过程中发生错误,可 rm -rf CMakeCache.txt 并解决异常项,再重新进行编译

预编译参数解析

$ cmake . \
-DCMAKE_INSTALL_PREFIX=/opt/mysql \            # 安装目录
-DMYSQL_DATADIR=/opt/mysql/data \              # 数据目录
-DMYSQL_UNIX_ADDR=/tmp/mysql.sock \            # 服务器侦听套接字连接的文件路径
-DSYSCONFDIR=/etc \                            # 配置文件目录
-DMYSQL_TCP_PORT=3306 \                        # 服务器侦听TCP/IP连接的端口号
-DWITH_INNOBASE_STORAGE_ENGINE=1 \             # 储存引擎 INNOBASE
-DWITH_PARTITION_STORAGE_ENGINE=1 \            # 储存引擎 PARTITION
-DWITH_FEDERATED_STORAGE_ENGINE=1 \            # 储存引擎 FEDERATED
-DWITH_BLACKHOLE_STORAGE_ENGINE=1 \            # 储存引擎 BLACKHOLE
-DWITH_MYISAM_STORAGE_ENGINE=1 \               # 储存引擎 MYISAM
-DWITH_EMBEDDED_SERVER=1 \                     # 嵌入式数据库
-DENABLED_LOCAL_INFILE=1 \                     # 从本地倒入数据
-DEXTRA_CHARSETS=all \                         # 扩展的字符集支持所有的
-DDEFAULT_CHARSET=utf8mb4 \                    # 默认字符集
-DDEFAULT_COLLATION=utf8mb4_general_ci \       # 服务器整理支持的
-DWITH_SSL=system \                            # 使用私钥和证书登陆(公钥)可以加密。 适用与长连接。坏处:速度慢
-DWITH_BOOST=boost                             # 指定boost 目录
安装需求 具体配置
安装目录(basedir) /usr/local/mysql
数据目录(datadir) /usr/local/mysql/data
端口号 3306
socket文件位置 $basedir/mysql.sock
字符集 utf8mb4
配置选项 描述 默认值 建议值
CMAKE_INSTALL_PREFIX 安装基目录 (basedir) /usr/local/mysql 根据需求
MYSQL_DATADIR 数据目录 (datadir) $basedir/data 根据需求
SYSCONFDIR 默认配置文件 my.cnf 路径 /etc
MYSQL_TCP_PORT TCP/IP 端口 3306 非默认端口
MYSQL_UNIX_ADDR 套接字 socket 文件路径 /tmp/mysql.sock $basedir/
DEFAULT_CHARSET 默认字符集 latin1 utf8mb4
DEFAULT_COLLATION 默认校验规则 latin1_swedish_ci utf8mb4_general_ci
WITH_EXTRA_CHARSETS 扩展字符集 all all
ENABLED_LOCAL_INFILE 是否启用本地加载外部数据文件功能 OFF 建议开启
WITH_SSL SSL 支持类型 system 建议显式指定
WITH_BOOST Boost 库源代码的位置 Boost 库是构建 MySQL 所必需的,建议事先下载

以下选项值均为布尔值,0 或 1;0 代表不编译到服务器中,1 代表编译,建议都静态编译到服务器中。

其他的存储引擎可以根据实际需求在安装时通过 WITH_xxxx_STORAGE_ENGINE=1 的方式编译到服务器中。

配置选项 描述
WITH_INNOBASE_STORAGE_ENGINE 将 InnoDB 存储引擎插件构建为静态模块编译到服务器中;建议编译到服务器中
WITH_PARTITION_STORAGE_ENGINE 是否支持分区
WITH_FEDERATED_STORAGE_ENGINE 本地数据库是否可以访问远程 mysql 数据
WITH_BLACKHOLE_STORAGE_ENGINE 黑洞存储引擎,接收数据,但不存储,直接丢弃
WITH_MYISAM_STORAGE_ENGINE 将 MYISAM 存储引擎静态编译到服务器中

4)编译安装(-j 参数是加快编译速度,代表同时开启多个线程共同实现编译操作)

$ make -j8 && make install

三. 初始配置

1)进入安装目录执行初始化操作,首先修改目录权限

$ cd /opt/mysql
$ chown -R mysql:mysql /opt/mysql

2)拷贝 mysql.server 脚本到 /etc/init.d 目录,配置启动项

$ cp support-files/mysql.server /etc/init.d/mysql

3)配置环境变量

1
2
3
4
$ echo 'export PATH=$PATH:/opt/mysql/bin' > /etc/profile.d/mysql.sh
$ source /etc/profile
$ mysql -V
mysql  Ver 14.14 Distrib 5.7.39, for Linux (x86_64) using  EditLine wrapper

4)前置工作完成后,进行初始化数据库

1
2
3
$ bin/mysqld --initialize --user=mysql --basedir=/opt/mysql --datadir=/opt/mysql/data
...
2022-04-03T02:43:31.295939Z 1 [Note] A temporary password is generated for root@localhost: e!m#BqYjf9OG

注:最后输出的是默认的密码,先记录起来,后期可进行修改

5)创建配置文件及参数优化

1
2
3
4
5
6
7
8
9
$ vim /etc/my.cnf
[client]
port = 3306
socket = /tmp/mysql.sock

[mysqld]
basedir = /opt/mysql
datadir = /opt/mysql/data
socket = /tmp/mysql.sock

参考配置,参数请根据实际需求进行配置,异常报错请自行查看 error 日志信息

# MySql5.7配置文件my.ini设置
[client]
port = 3306
socket = /tmp/mysql.sock

[mysqld]
###############################基础设置#####################################
#Mysql服务的唯一编号 每个mysql服务Id需唯一
server-id = 1

#服务端口号 默认3306
port = 3306

#mysql安装根目录
basedir = /opt/mysql

#mysql数据文件所在位置
datadir = /opt/mysql/data

#临时目录 比如load data infile会用到
tmpdir  = /tmp

#设置socke文件所在目录
socket  = /tmp/mysql.sock

#主要用于MyISAM存储引擎,如果多台服务器连接一个数据库则建议注释下面内容
skip-external-locking

#只能用IP地址检查客户端的登录,不用主机名
skip_name_resolve = 1
#数据库默认字符集,主流字符集支持一些特殊表情符号(特殊表情符占用4个字节)
character-set-server = utf8mb4

#数据库字符集对应一些排序等规则,注意要和character-set-server对应
collation-server = utf8mb4_general_ci

#设置client连接mysql时的字符集,防止乱码
init_connect='SET NAMES utf8mb4'

#是否对sql语句大小写敏感,1表示不敏感
lower_case_table_names = 1

#最大连接数
max_connections = 400
#最大错误连接数
max_connect_errors = 1000

#TIMESTAMP如果没有显示声明NOT NULL,允许NULL值
explicit_defaults_for_timestamp = true

#SQL数据包发送的大小,如果有BLOB对象建议修改成1G
max_allowed_packet = 128M

#MySQL连接闲置超过一定时间后(单位:秒)将会被强行关闭
#MySQL默认的wait_timeout  值为8个小时, interactive_timeout参数需要同时配置才能生效
interactive_timeout = 1800
wait_timeout = 1800

#内部内存临时表的最大值 ,设置成128M。
#比如大数据量的group by ,order by时可能用到临时表,
#超过了这个值将写入磁盘,系统IO压力增大
tmp_table_size = 134217728
max_heap_table_size = 134217728

##----------------------------用户进程分配到的内存设置BEGIN-----------------------------##
##每个session将会分配参数设置的内存大小
#用于表的顺序扫描,读出的数据暂存于read_buffer_size中,当buff满时或读完,将数据返回上层调用者
#一般在128kb ~ 256kb,用于MyISAM
#read_buffer_size = 131072
#用于表的随机读取,当按照一个非索引字段排序读取时会用到,
#一般在128kb ~ 256kb,用于MyISAM
#read_rnd_buffer_size = 262144
#order by或group by时用到
#建议先调整为2M,后期观察调整
sort_buffer_size = 2097152
#一般数据库中没什么大的事务,设成1~2M,默认32kb
binlog_cache_size = 524288

############################日  志 设置##########################################
#数据库错误日志文件
log_error = error.log

#慢查询sql日志设置
slow_query_log = 1
slow_query_log_file = slow.log
#检查未使用到索引的sql
log_queries_not_using_indexes = 1
#针对log_queries_not_using_indexes开启后,记录慢sql的频次、每分钟记录的条数
log_throttle_queries_not_using_indexes = 5
#作为从库时生效,从库复制中如何有慢sql也将被记录
log_slow_slave_statements = 1
#慢查询执行的秒数,必须达到此值可被记录
long_query_time = 2
#检索的行数必须达到此值才可被记为慢查询
min_examined_row_limit = 100

#mysql binlog日志文件保存的过期时间,过期后自动删除
expire_logs_days = 5

############################主从复制 设置########################################
#开启mysql binlog功能
log-bin=mysql-bin
#binlog记录内容的方式,记录被操作的每一行
binlog_format = ROW

#作为从库时生效,想进行级联复制,则需要此参数
log_slave_updates

#作为从库时生效,中继日志relay-log可以自我修复
relay_log_recovery = 1

#作为从库时生效,主从复制时忽略的错误
slave_skip_errors = ddl_exist_errors

##---redo log和binlog的关系设置BEGIN---##
#(步骤1) prepare dml相关的SQL操作,然后将redo log buff中的缓存持久化到磁盘
#(步骤2)如果前面prepare成功,那么再继续将事务日志持久化到binlog
#(步骤3)如果前面成功,那么在redo log里面写上一个commit记录
#当innodb_flush_log_at_trx_commit和sync_binlog都为1时是最安全的,
#在mysqld服务崩溃或者服务器主机crash的情况下,binary log只有可能丢失最多一个语句或者一个事务。
#但是都设置为1时会导致频繁的io操作,因此该模式也是最慢的一种方式。
#当innodb_flush_log_at_trx_commit设置为0,mysqld进程的崩溃会导致上一秒钟所有事务数据的丢失。
#当innodb_flush_log_at_trx_commit设置为2,只有在操作系统崩溃或者系统掉电的情况下,上一秒钟所有事务数据才可能丢失。
#commit事务时,控制redo log buff持久化磁盘的模式 默认为1
innodb_flush_log_at_trx_commit = 2
#commit事务时,控制写入mysql binlog日志的模式 默认为 0
#innodb_flush_log_at_trx_commit和sync_binlog都为1时,mysql最为安全但性能上压力也是最大
sync_binlog = 1
##---redo log 和 binlog的关系设置END---##

############################Innodb设置##########################################
#数据块的单位8k,默认是16k,16kCPU压力稍小,8k对select的吞吐量大
#innodb_page_size的参数值也影响最大索引长度,8k比16k的最大索引长度小
#innodb_page_size = 8192
#一般设置物理存储的60% ~ 70%
innodb_buffer_pool_size = 1G

#5.7.6之后默认16M
#innodb_log_buffer_size = 16777216
#该参数针对unix、linux,window上直接注释该参数.默认值为NULL
#O_DIRECT减少操作系统级别VFS的缓存和Innodb本身的buffer缓存之间的冲突
innodb_flush_method = O_DIRECT

#此格式支持压缩, 5.7.7之后为默认值
innodb_file_format = Barracuda

#CPU多核处理能力设置,假设CPU是2颗4核的,设置如下
#读多,写少可以设成2:6的比例
innodb_write_io_threads = 4
innodb_read_io_threads = 4

#提高刷新脏页数量和合并插入数量,改善磁盘I/O处理能力
#默认值200(单位:页)
#可根据磁盘近期的IOPS确定该值
innodb_io_capacity = 500

#为了获取被锁定的资源最大等待时间,默认50秒,超过该时间会报如下错误:
# ERROR 1205 (HY000): Lock wait timeout exceeded; try restarting transaction
innodb_lock_wait_timeout = 30

#调整buffer pool中最近使用的页读取并dump的百分比,通过设置该参数可以减少转储的page数
innodb_buffer_pool_dump_pct = 40

#设置redoLog文件所在目录, redoLog记录事务具体操作内容
innodb_log_group_home_dir = /opt/mysql/redolog/

#设置undoLog文件所在目录, undoLog用于事务回滚操作
innodb_undo_directory = /opt/mysql/undolog/

#在innodb_log_group_home_dir中的redoLog文件数, redoLog文件内容是循环覆盖写入。
innodb_log_files_in_group = 3

#MySql5.7官方建议尽量设置的大些,可以接近innodb_buffer_pool_size的大小
#之前设置该值较大时可能导致mysql宕机恢复时间过长,现在恢复已经加快很多了
#该值减少脏数据刷新到磁盘的频次
#最大值innodb_log_file_size * innodb_log_files_in_group <= 512GB,单文件<=256GB
innodb_log_file_size = 1024M

#设置undoLog文件所占空间可以回收
#5.7之前的MySql的undoLog文件一直增大无法回收
innodb_undo_log_truncate = 1
innodb_undo_tablespaces = 3
innodb_undo_logs = 128

#5.7.7默认开启该参数 控制单列索引长度最大达到3072
#innodb_large_prefix = 1

#5.7.8默认为4个, Inodb后台清理工作的线程数
#innodb_purge_threads = 4

#通过设置配置参数innodb_thread_concurrency来限制并发线程的数量,
#一旦执行线程的数量达到这个限制,额外的线程在被放置到对队列中之前,会睡眠数微秒,
#可以通过设定参数innodb_thread_sleep_delay来配置睡眠时间
#该值默认为0,在官方doc上,对于innodb_thread_concurrency的使用,也给出了一些建议:
#(1)如果一个工作负载中,并发用户线程的数量小于64,建议设置innodb_thread_concurrency=0;
#(2)如果工作负载一直较为严重甚至偶尔达到顶峰,建议先设置innodb_thread_concurrency=128,
###并通过不断的降低这个参数,96, 80, 64等等,直到发现能够提供最佳性能的线程数
#innodb_thread_concurrency = 0
############################其他内容 设置##########################################
[mysqldump]
quick
max_allowed_packet = 128M
[mysql]
no-auto-rehash
[myisamchk]
key_buffer_size = 20M
sort_buffer_size = 256k
read_buffer = 2M
write_buffer = 2M
[mysqlhotcopy]
interactive-timeout
[mysqld_safe]
#增加每个进程的可打开文件数量.
open-files-limit = 28192

6)启动服务,并设置开机自启

$ service mysql start
$ chkconfig --add mysql
$ chkconfig mysql on
$ chkconfig mysql --list
Note: This output shows SysV services only and does not include native
      systemd services. SysV configuration data might be overridden by native
      systemd configuration.

      If you want to list systemd services use 'systemctl list-unit-files'.
      To see services enabled on particular target use
      'systemctl list-dependencies [target]'.

mysql           0:off   1:off   2:on    3:on    4:on    5:on    6:off
$ service mysql status
 SUCCESS! MySQL running (2450)
$ systemctl status mysql
 mysql.service - LSB: start and stop MySQL
   Loaded: loaded (/etc/rc.d/init.d/mysql; bad; vendor preset: disabled)
   Active: active (running) since Wed 2022-10-12 15:10:50 CST; 1h 19min ago
     Docs: man:systemd-sysv-generator(8)
  Process: 1531 ExecStart=/etc/rc.d/init.d/mysql start (code=exited, status=0/SUCCESS)
    Tasks: 36
   Memory: 298.2M
   CGroup: /system.slice/mysql.service
           ├─1553 /bin/sh /opt/mysql/bin/mysqld_safe --datadir=/opt/mysql/data --pid-file=/opt/mysql/data/dell-2005-formal.server.pid
           └─2450 /opt/mysql/bin/mysqld --basedir=/opt/mysql --datadir=/opt/mysql/data --plugin-dir=/opt/mysql/lib/plugin --user=mysql --log-error=error.log --open-fi...

Oct 12 15:10:46 dell-2005-formal.server systemd[1]: Starting LSB: start and stop MySQL...
Oct 12 15:10:50 dell-2005-formal.server mysql[1531]: Starting MySQL... SUCCESS!
Oct 12 15:10:50 dell-2005-formal.server systemd[1]: Started LSB: start and stop MySQL.

启动服务脚本文件参考

# 启动文件参考
$ cat /etc/systemd/system/mysqld.service
[Unit]
Description=MySQL Server
Documentation=man:mysqld(7)
Documentation=http://dev.mysql.com/doc/refman/en/using-systemd.html
After=network.target
After=syslog.target

[Install]
WantedBy=multi-user.target

[Service]
User=mysql
Group=mysql

Type=forking
PIDFile=/opt/mysql/data/mysqld.pid
TimeoutSec=0

ExecStart=/opt/mysql/bin/mysqld --defaults-file=/opt/mysql/etc/my.cnf --daemonize --pid-file=/opt/mysql/data/mysqld.pid $MYSQLD_OPTS 
EnvironmentFile=-/etc/sysconfig/mysql

LimitNOFILE = 5000
Restart=on-failure
RestartPreventExitStatus=1
PrivateTmp=false

四. 安全配置

1)修改本地管理员密码,也可直接 mysql -uroot -p 进行修改

1
2
3
4
$ bin/mysqladmin -uroot password 'newpassword' -p
Enter password:e!m#BqYjf9OG
mysqladmin: [Warning] Using a password on the command line interface can be insecure.
Warning: Since password will be sent to server in plain text, use ssl connection to ensure password safety.

2)修改安全选项

1
2
3
4
5
6
7
8
9
$ bin/mysql_secure_installation
# 步骤说明:如前面已修改过密码,前三个步骤可直接回车忽略
步骤1:输入root密码(默认为空,直接回车)
步骤2:设置root密码,输入Y
步骤3:输入密码
步骤4:是否移除匿名用户,输入Y
步骤5:不允许root远程登录,输入Y
步骤6:是否允许移除test数据库,输入Y(生产环境删除更安全)
步骤7:重新加载权限表,输入Y(修改的密码马上生效)

3)开启远程管理

mysql> GRANT ALL ON *.* TO root@'%' IDENTIFIED BY 'password' WITH GRANT OPTION;
mysql> flush privileges;