[MYSQL] centos7.9编译mysql 8.0.37作为调试环境

2024-06-11 18:15:15 浏览数 (1)

导读

作为一个mysql dba, 难免会接触到mysql源码, 光看的话, 不好理解, 效率也不高, 就得改一改, 跑一跑. 那么就需要一个环境. 本文就是来搭建这么一个环境的.

环境准备

需要centos 7.9 能连外网的, 或者有本地的sclo源也行. 主要是得安装一些依赖包.

编译mysql 8.0.37 需要如下环境, 参考:https://dev.mysql.com/doc/refman/8.0/en/source-installation-prerequisites.html

代码语言:shell复制
环境要求:
devtoolset-11-gcc devtoolset-11-gcc-c   devtoolset-11-binutils

编译软件版本要求:
GCC >= 10  make >= 3.75 cmake >= 3.11.2

gcc安装要求:
GMP 4.2 , MPFR 3.1.0  and MPC 0.8.0 

我们一个个来. 直接整最新的版本.

依赖安装

先安装那一堆开发环境的包.

代码语言:shell复制
# 配置sclo yum源
cat <<EOF >/etc/yum.repos.d/base_sclo.repo
[sclo]
name=sclo
baseurl=http://mirrors.tuna.tsinghua.edu.cn/centos-vault/7.9.2009/sclo/x86_64/rh/
enabled=1
gpgcheck=0
EOF

# 安装依赖
yum repolist
yum install devtoolset-11-gcc devtoolset-11-gcc-c   devtoolset-11-binutils -y

cmake安装

cmake有二进制的, 我们直接下载就行

代码语言:shell复制
mkdir -p ~/cmake
cd ~/cmake
wget https://cmake.org/files/v3.30/cmake-3.30.0-rc1-linux-x86_64.tar.gz
tar -xvf cmake-3.30.0-rc1-linux-x86_64.tar.gz
export PATH=~/cmake-3.30.0-rc1-linux-x86_64/bin:$PATH #就临时配置一下吧. 需要的话, 可以配置 profile

GMP 安装

得编译安装

代码语言:shell复制
mkdir -p ~/gmp
cd ~/gmp
wget https://mirror.tuna.tsinghua.edu.cn/gnu/gmp/gmp-6.3.0.tar.gz
tar -xvf gmp-6.3.0.tar.gz
cd gmp-6.3.0
./configure --prefix=/usr/local/gmp-6.3.0
make -j 4 && make install

MPFR 安装

源码编译安装

代码语言:shell复制
mkdir -p ~/mpfr
cd ~/mpfr
wget https://mirror.tuna.tsinghua.edu.cn/gnu/mpfr/mpfr-4.2.1.tar.gz
tar -xvf mpfr-4.2.1.tar.gz
cd mpfr-4.2.1
./configure --prefix=/usr/local/mpfr-4.2.1
make -j 4 && make install

MPC 安装

有个小坑是 gcc 做configure的时候找不到mpc.h. 得引入下stdio才行.

代码语言:shell复制
mkdir -p ~/mpc
cd ~/mpc
wget https://mirror.tuna.tsinghua.edu.cn/gnu/mpc/mpc-1.3.0.tar.gz
tar -xvf mpc-1.3.0.tar.gz
cd mpc-1.3.0
sed -i '/#include <stdint.h>/a#include <stdio.h>' src/mpc.h # 直接源码里面加上就行.
./configure --prefix=/usr/local/mpc-1.3.0
make -j 4 && make install

GCC 安装

终于安装gcc了

代码语言:shell复制
mkdir -p ~/gcc
cd ~/gcc
wget https://mirror.tuna.tsinghua.edu.cn/gnu/gcc/gcc-13.3.0/gcc-13.3.0.tar.gz
tar -xvf gcc-13.3.0.tar.gz
cd gcc-13.3.0
./configure --prefix=/usr/local/gcc-13.3.0 
--enable-threads=posix 
--disable-checking 
--disable-multilib 
--enable-languages=c,c    
--with-gmp=/usr/local/gmp-6.3.0 
--with-mpfr=/usr/local/mpfr-4.2.1/ 
--with-mpc=/usr/local/mpc-1.3.0/
make -j 4 && make install 

编译MYSQL

上面那一大堆步骤都是准备环境, 现在开始编译mysql

代码语言:shell复制
mkdir ~/mysql_source
cd ~/mysql_source
wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
tar -xvf mysql-8.0.37-linux-glibc2.17-x86_64.tar.xz
cd mysql-8.0.37
mkdir bldx86 # 单独一个目录来编译方便点
cd bldx86
cmake .. -DBUILD_CONFIG=mysql_release
make -j 4 #编译很慢
make package #打包(可选, 我们这里就不打包了, 我们还得修改代码呢)

使用

我们直接使用编译好的mysqld来初始化和启动数据库

代码语言:shell复制
# 目录创建
mkdir -p /data/mysql_dev/data
mkdir -p /data/mysql_dev/log
mkdir -p /data/mysql_dev/run

# 配置文件整上
cat << EOF > /data/mysql_dev/my.cnf
[mysqld]
user=mysql
bind_address=0.0.0.0
port=3306
basedir=/root/mysql_source/mysql-8.0.37/bldx86
datadir=/data/mysql_dev/data
socket=/data/mysql_dev/run/mysql.sock
pid_file=/data/mysql_dev/run/mysql.pid
tmpdir=/data/mysql_dev/run
log_error=/data/mysql_dev/log/mysql.err
log_bin=/data/mysql_dev/log/mysql-bin
EOF
chown mysql:mysql /data/mysql_dev -R

# 初始化
/root/mysql_source/mysql-8.0.37/bldx86/runtime_output_directory/mysqld --defaults-file=/data/mysql_dev/my.cnf --initialize-insecure


# 启动 (--daemonize 也可以放后台)
nohup /root/mysql_source/mysql-8.0.37/bldx86/runtime_output_directory/mysqld  --defaults-file=/data/mysql_dev/my.cnf &

# 修改密码(第一次要改密码)
mysql -S /data/mysql_dev/run/mysql.sock # 使用socket登录
alter user root@'localhost' identified with mysql_native_password by '123456'; -- 第一次登录必须先修改密码
create user root@'%' identified with mysql_native_password by '123456'; -- 建个普通用户方便我们使用
grant all on *.* to root@'%'; -- 这个用户其实也不普通
flush privileges;

# 停止
kill `cat /data/mysql_dev/run/mysql.pid`

# 配置成脚本或者服务更方便, 按照自己的习惯来吧, 我这里就不提供了.

调试演示

上面的步骤都完成之后, 就得到了一个调试环境. 可以修改源码,然后编译验证了.

演示一下吧, 我们知道 mysqld 启动的时候会自动启动主从复制进程. 那么我们可以修改源码来不让它自动启动.

编辑 sql/mysqld.cc 中的 mysqld_main 函数里面关于主从启动的代码. 简单点, 我们直接加个opt_skip_replica_start=true, 即相当于默认加上 --skip-slave-start.

replica_initializer 之前加上就行. 比如:

代码语言:c 复制
  opt_skip_replica_start = true; /* 不启动主从 */

  check_binlog_cache_size(nullptr);
  check_binlog_stmt_cache_size(nullptr);

  binlog_unsafe_map_init();

  ReplicaInitializer replica_initializer(opt_initialize, opt_skip_replica_start,
                                         rpl_channel_filters,
                                         &opt_replica_skip_errors);

然后重新编译(make -j 4), 之后编译修改的部分, 然后重新组装到mysqld里面

代码语言:shell复制
[ 87%] Built target routertest_component_mock_server
[ 87%] Built target sql_gis
[ 87%] Building CXX object sql/CMakeFiles/sql_main.dir/mysqld.cc.o
[ 87%] Linking CXX static library ../archive_output_directory/libsql_main.a
[ 93%] Built target sql_main
[ 96%] Built target innobase
[ 96%] Linking CXX shared library library_output_directory/libserver_unittest_library.so
[ 96%] Linking CXX executable ../runtime_output_directory/mysqld
[ 96%] Built target mysqld
[ 96%] Built target INFO_BIN
[ 96%] Built target server_unittest_library
[ 96%] Linking CXX executable ../../../runtime_output_directory/pfs_connect_attr-t
[ 96%] Linking CXX executable ../../../runtime_output_directory/merge_keyring_file_tests-t
[ 96%] Linking CXX executable ../../../runtime_output_directory/merge_innodb_tests-t
[ 96%] Linking CXX executable ../../runtime_output_directory/merge_large_tests-t
[ 96%] Built target pfs_connect_attr-t
[ 96%] Linking CXX executable ../../../../plugin_output_directory/minimal_chassis_test_driver-t
[ 96%] Built target merge_keyring_file_tests-t
[ 96%] Linking CXX executable ../../../../plugin_output_directory/reference_cache-t
[ 96%] Built target minimal_chassis_test_driver-t
[ 96%] Linking CXX executable ../../../runtime_output_directory/group_replication_member_info-t
[ 96%] Built target reference_cache-t
[ 96%] Linking CXX executable ../../../runtime_output_directory/group_replication_compatibility_module-t
[ 96%] Built target group_replication_member_info-t
[ 96%] Linking CXX executable ../../../runtime_output_directory/group_replication_member_version-t
[ 96%] Built target merge_innodb_tests-t
[ 97%] Linking CXX executable ../../../runtime_output_directory/group_replication_mysql_version_gcs_protocol_map-t
[ 97%] Built target group_replication_compatibility_module-t
[ 97%] Linking CXX executable ../../../runtime_output_directory/group_replication_gcs_mysql_network_provider-t
[ 97%] Built target group_replication_member_version-t
[ 97%] Linking CXX executable ../../../runtime_output_directory/merge_temptable_tests-t
[ 97%] Built target group_replication_mysql_version_gcs_protocol_map-t
[ 97%] Linking CXX executable ../../../runtime_output_directory/gtid_set-t
[ 97%] Built target group_replication_gcs_mysql_network_provider-t
[ 97%] Built target merge_temptable_tests-t
[ 97%] Built target gtid_set-t
[100%] Built target merge_large_tests-t
16:27:38 [root@ddcw21 bldx86]#make -j 4

然后再次启动mysqld 发现就没得之前的那些repl信息了

登录数据库确认一下: 主从进程没启动(也没报错)

代码语言:sql复制
(root@127.0.0.1) [(none)]> show slave statusG
*************************** 1. row ***************************
               Slave_IO_State: 
                  Master_Host: 192.168.101.21
                  Master_User: repl
                  Master_Port: 3314
                Connect_Retry: 60
              Master_Log_File: 
          Read_Master_Log_Pos: 4
               Relay_Log_File: ddcw21-relay-bin.000001
                Relay_Log_Pos: 4
        Relay_Master_Log_File: 
             Slave_IO_Running: No
            Slave_SQL_Running: No
              Replicate_Do_DB: 
          Replicate_Ignore_DB: 
           Replicate_Do_Table: 
       Replicate_Ignore_Table: 
      Replicate_Wild_Do_Table: 
  Replicate_Wild_Ignore_Table: 
                   Last_Errno: 0
                   Last_Error: 
                 Skip_Counter: 0
          Exec_Master_Log_Pos: 0
              Relay_Log_Space: 697
              Until_Condition: None
               Until_Log_File: 
                Until_Log_Pos: 0
           Master_SSL_Allowed: No
           Master_SSL_CA_File: 
           Master_SSL_CA_Path: 
              Master_SSL_Cert: 
            Master_SSL_Cipher: 
               Master_SSL_Key: 
        Seconds_Behind_Master: NULL
Master_SSL_Verify_Server_Cert: No
                Last_IO_Errno: 0
                Last_IO_Error: 
               Last_SQL_Errno: 0
               Last_SQL_Error: 
  Replicate_Ignore_Server_Ids: 
             Master_Server_Id: 0
                  Master_UUID: 
             Master_Info_File: mysql.slave_master_info
                    SQL_Delay: 0
          SQL_Remaining_Delay: NULL
      Slave_SQL_Running_State: 
           Master_Retry_Count: 86400
                  Master_Bind: 
      Last_IO_Error_Timestamp: 
     Last_SQL_Error_Timestamp: 
               Master_SSL_Crl: 
           Master_SSL_Crlpath: 
           Retrieved_Gtid_Set: 
            Executed_Gtid_Set: 
                Auto_Position: 0
         Replicate_Rewrite_DB: 
                 Channel_Name: 
           Master_TLS_Version: 
       Master_public_key_path: 
        Get_master_public_key: 0
            Network_Namespace: 
1 row in set, 1 warning (0.00 sec)

总结

至此我们就得到了一个mysql的调试环境, 可以随便调试了.

编程语言其实基本上都差不多的, 会一门语言, 其它的基本上就能看懂, 然后慢慢调试, 慢慢理解.

0 人点赞