#!/bin/bash
set -e  # 任何错误都立即退出

# 颜色定义
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color

# 日志函数
log_info() { echo -e "${GREEN}[INFO]${NC} $1"; }
log_warn() { echo -e "${YELLOW}[WARN]${NC} $1"; }
log_error() { echo -e "${RED}[ERROR]${NC} $1"; }

# 配置变量
MYSQL_VERSION="8.0.44"
CMAKE_VERSION="3.26.0"
SOFT_PATH="/root/software"
MYSQL_PREFIX="/opt/mysql"
MYSQL_USER="mysql"
MYSQL_UID=502
MYSQL_GID=502

log_info "开始安装 MySQL ${MYSQL_VERSION} on CentOS 9"

# 1. 创建 MySQL 用户
log_info "创建 MySQL 用户..."
if ! id "${MYSQL_USER}" &>/dev/null; then
    groupadd -g ${MYSQL_GID} ${MYSQL_USER} 2>/dev/null || true
    useradd -s /sbin/nologin -M -u ${MYSQL_UID} -g ${MYSQL_USER} ${MYSQL_USER}
    log_info "MySQL 用户创建成功"
else
    log_warn "MySQL 用户已存在，跳过创建"
fi

# 2. 创建软件目录
log_info "创建软件目录..."
mkdir -p ${SOFT_PATH}
cd ${SOFT_PATH}

# 3. 安装基础工具
log_info "安装基础依赖包..."
yum -y install wget git curl

# 4. 安装 CMake
log_info "安装 CMake ${CMAKE_VERSION}..."
if [ ! -d "/usr/local/cmake" ]; then
    CMAKE_FILE="cmake-${CMAKE_VERSION}-linux-x86_64.tar.gz"
    if [ ! -f "${CMAKE_FILE}" ]; then
        wget -q https://github.com/Kitware/CMake/releases/download/v${CMAKE_VERSION}/${CMAKE_FILE}
    fi
    tar zxf ${CMAKE_FILE}
    mv cmake-${CMAKE_VERSION}-linux-x86_64 /usr/local/cmake
    echo "export PATH=/usr/local/cmake/bin:\$PATH" >> /etc/profile
    source /etc/profile
    log_info "CMake 安装成功"
else
    log_warn "CMake 已安装，跳过"
fi

# 5. 安装编译工具链和依赖库
log_info "安装编译工具链和开发库..."
yum -y install gcc gcc-c++ make \
    libaio libaio-devel libcurl-devel \
    ncurses-devel bison bzip2 openssl-devel \
    rpcgen pkg-config \
    perl perl-devel systemd-devel glibc-devel

# 6. 安装 GCC Toolset-12
log_info "安装 GCC Toolset-12..."
yum -y install gcc-toolset-12-gcc gcc-toolset-12-gcc-c++ gcc-toolset-12-binutils
source /opt/rh/gcc-toolset-12/enable

sudo dnf config-manager --set-enabled crb
sudo dnf install -y libtirpc-devel libnsl2-devel

# 7. 下载和解压 MySQL（源码包已含 boost）
log_info "下载 MySQL ${MYSQL_VERSION}..."
cd ${SOFT_PATH}

MYSQL_FILE="mysql-boost-${MYSQL_VERSION}.tar.gz"
MYSQL_DIR="mysql-${MYSQL_VERSION}"

if [ ! -d "${MYSQL_DIR}" ]; then
    if [ ! -f "${MYSQL_FILE}" ]; then
        log_info "正在下载 MySQL ${MYSQL_VERSION}（包含 boost）..."
        wget https://dev.mysql.com/get/Downloads/MySQL-8.0/${MYSQL_FILE}
        log_info "MySQL ${MYSQL_VERSION} 下载完成"
    fi
    log_info "解压 MySQL..."
    tar zxf ${MYSQL_FILE}
else
    log_warn "MySQL 目录已存在，跳过下载"
fi

cd ${SOFT_PATH}/${MYSQL_DIR}

# 8. 配置和编译
log_info "开始配置 MySQL..."

log_info "运行 CMake 配置..."
cmake . \
-DWITH_BOOST=./boost/ \
-DMYSQL_UNIX_ADDR=/opt/mysql/tmp/mysql.sock \
-DCMAKE_INSTALL_PREFIX=/opt/mysql \
-DMYSQL_DATADIR=/opt/mysql/var \
-DWITHOUT_CSV_STORAGE_ENGINE=1 \
-DWITHOUT_FEDERATED_STORAGE_ENGINE=1 \
-DWITHOUT_ARCHIVE_STORAGE_ENGINE=1 \
-DWITHOUT_MRG_MYISAM_STORAGE_ENGINE=1 \
-DWITHOUT_NDBCLUSTER_STORAGE_ENGINE=1 \
-DFORCE_INSOURCE_BUILD=1

log_info "开始编译 MySQL（此过程需要较长时间...）"
CORES=$(nproc)
log_info "使用 ${CORES} 个 CPU 核心进行编译"
make -j${CORES}

log_info "编译完成，开始安装..."
make install

# 9. 创建必要的目录和权限
log_info "创建数据目录和权限配置..."
mkdir -p ${MYSQL_PREFIX}/{var,tmp}
chmod 750 ${MYSQL_PREFIX}/{var,tmp}
chown -R ${MYSQL_USER}:${MYSQL_USER} ${MYSQL_PREFIX}

# 10. 生成配置文件
log_info "生成 MySQL 配置文件..."
cat > ${MYSQL_PREFIX}/my.cnf << 'EOF'
[client]
#password        = [your_password]
port             = 3306
socket           = /tmp/mysql.sock
# *** Application-specific options follow here ***
 
#
# The MySQL server
#
[mysqld]
# *** generic configuration options ***
port             = 3306
socket           = /tmp/mysql.sock
pid-file         = /opt/mysql/var/mysqld.pid
user             = mysql
 
basedir          = /opt/mysql
datadir          = /opt/mysql/var
 
wait_timeout     = 10
skip-name-resolve

default_authentication_plugin=caching_sha2_password

character-set-server = utf8mb4
skip_name_resolve = 1
open_files_limit = 65535
back_log = 1024
max_connections = 10000
max_connect_errors = 1000000

table_open_cache = 2048
table_definition_cache = 2048
table_open_cache_instances = 64
lower_case_table_names = 1

thread_stack = 512K
external-locking = FALSE
max_allowed_packet = 32M
sort_buffer_size = 16M
join_buffer_size = 16M
thread_cache_size = 3000
interactive_timeout = 7200
wait_timeout = 7200

tmp_table_size = 96M
max_heap_table_size = 96M

slow_query_log = 1
slow_query_log_file = /opt/mysql/var/slow.log
log-error = /opt/mysql/var/error.log
long_query_time = 3
log_queries_not_using_indexes =1
log_throttle_queries_not_using_indexes = 60
min_examined_row_limit = 100
log_slow_admin_statements = 1
log_slow_replica_statements = 1
log_timestamps=SYSTEM

server-id = 1
log-bin = mysql-bin
#relay-log = /opt/mysql/var/relay-log
sync_binlog = 1
binlog_cache_size = 4M
max_binlog_cache_size = 2G
max_binlog_size = 1G
expire_logs_days = 30
master_info_repository = TABLE
relay_log_info_repository = TABLE

gtid_mode = on
enforce_gtid_consistency = 1
log_replica_updates
slave-rows-search-algorithms = 'INDEX_SCAN,HASH_SCAN'
binlog_format = row
binlog_checksum = 1
relay_log_recovery = 1
relay-log-purge = 1

key_buffer_size = 32M
read_buffer_size = 8M
read_rnd_buffer_size = 16M
bulk_insert_buffer_size = 64M
myisam_sort_buffer_size = 128M
myisam_max_sort_file_size = 10G
lock_wait_timeout = 3600
explicit_defaults_for_timestamp = 1

innodb_thread_concurrency = 0
innodb_sync_spin_loops = 100
innodb_spin_wait_delay = 30

transaction_isolation = REPEATABLE-READ
#innodb_additional_mem_pool_size = 16M
innodb_buffer_pool_size = 1G
innodb_buffer_pool_instances = 8
innodb_buffer_pool_load_at_startup = 1
innodb_buffer_pool_dump_at_shutdown = 1
#innodb_data_file_path = ibdata1:1G:autoextend
innodb_flush_log_at_trx_commit = 1
innodb_log_buffer_size = 32M
# Deprecated in MySQL 8.0.22+: replace innodb_log_file_size and
# innodb_log_files_in_group with innodb_redo_log_capacity (bytes).
# Previous settings: innodb_log_file_size = 2G, innodb_log_files_in_group = 2
# innodb_log_file_size = 2G
# innodb_log_files_in_group = 2
innodb_redo_log_capacity = 4294967296
innodb_max_undo_log_size = 2G
#innodb_undo_directory = undolog
#innodb_undo_tablespaces = 95

# 根据您的服务器IOPS能力适当调整
innodb_io_capacity = 4000
innodb_io_capacity_max = 8000
innodb_flush_neighbors = 0
innodb_write_io_threads = 4
innodb_read_io_threads = 4
innodb_purge_threads = 4
innodb_page_cleaners = 4
innodb_open_files = 65535
innodb_max_dirty_pages_pct = 50
innodb_flush_method = O_DIRECT
innodb_lru_scan_depth = 4000
innodb_checksum_algorithm = crc32
innodb_lock_wait_timeout = 10
innodb_rollback_on_timeout = 1
innodb_print_all_deadlocks = 1
innodb_file_per_table = 1
innodb_online_alter_log_max_size = 4G
innodb_stats_on_metadata = 0
[mysqldump]
quick
max_allowed_packet = 32M
EOF

chmod 644 ${MYSQL_PREFIX}/my.cnf

# 11. 初始化数据库
log_info "初始化 MySQL 数据库..."
${MYSQL_PREFIX}/bin/mysqld \
  --defaults-file=${MYSQL_PREFIX}/my.cnf \
  --initialize-insecure \
  --datadir=${MYSQL_PREFIX}/var \
  --user=${MYSQL_USER} \
  --basedir=${MYSQL_PREFIX}

log_info "数据库初始化完成"

# 12. 设置环境变量
log_info "配置环境变量..."
cat >> /etc/profile << EOF
export PATH=${MYSQL_PREFIX}/bin:\$PATH
export LD_LIBRARY_PATH=${MYSQL_PREFIX}/lib:\$LD_LIBRARY_PATH
EOF
source /etc/profile

# 13. 创建 systemd 服务文件
log_info "创建 systemd 服务文件..."
cat > /etc/systemd/system/mysql.service << EOF
[Unit]
Description=MySQL Server
After=network.target

[Service]
Type=forking

User=${MYSQL_USER}
Group=${MYSQL_USER}
PIDFile=/opt/mysql/var/mysqld.pid
ExecStart=/opt/mysql/bin/mysqld --defaults-file=/opt/mysql/my.cnf  --daemonize
ExecStop=/opt/mysql/bin/mysqladmin -S /opt/mysql/tmp/mysql.sock shutdown
Restart=on-failure
RestartSec=5s
LimitNOFILE=65535
LimitNPROC=65535

[Install]
WantedBy=multi-user.target
EOF

chmod 644 /etc/systemd/system/mysql.service
systemctl daemon-reload

# 14. 验证安装
log_info "验证 MySQL 安装..."
if ${MYSQL_PREFIX}/bin/mysqld --version | grep -q "8.0"; then
    log_info "MySQL 版本验证成功"
else
    log_error "MySQL 版本验证失败"
    exit 1
fi

# 15. 启动 MySQL
log_info "启动 MySQL 服务..."
systemctl enable mysql
systemctl start mysql
sleep 3

# 16. 验证服务
log_info "验证 MySQL 服务状态..."
if systemctl is-active --quiet mysql; then
    log_info "MySQL 服务启动成功"
    ${MYSQL_PREFIX}/bin/mysql -S ${MYSQL_PREFIX}/tmp/mysql.sock -u root -e "SELECT version();" 2>/dev/null || true
else
    log_error "MySQL 服务启动失败，请检查日志"
    systemctl status mysql
    tail -100 ${MYSQL_PREFIX}/var/error.log
    exit 1
fi

# 17. 完成信息
echo ""
echo "========================================"
echo -e "${GREEN}MySQL ${MYSQL_VERSION} 安装完成！${NC}"
echo "========================================"
echo "安装路径: ${MYSQL_PREFIX}"
echo "数据目录: ${MYSQL_PREFIX}/var"
echo "Socket: ${MYSQL_PREFIX}/tmp/mysql.sock"
echo "配置文件: ${MYSQL_PREFIX}/my.cnf"
echo ""
echo "常用命令:"
echo "  连接: mysql -S ${MYSQL_PREFIX}/tmp/mysql.sock -u root"
echo "  重启: systemctl restart mysql"
echo "  日志: tail -f ${MYSQL_PREFIX}/var/error.log"
echo ""
echo "修改密码:"
echo "  ALTER USER 'root'@'localhost' IDENTIFIED BY 'password';"
echo "========================================"

log_info "安装完成"



