0
0
0
0
博客/.../

openEuler 部署 TiDB:锁索引故障 + Sysbench 实战

 ShunWahMA  发表于  2026-08-07

openEuler 22.03 SP4 部署 TiDB v8.5|锁索引故障与 Sysbench 实战

fd4fcd074bfc48519ad4514893fb2122.jpeg~tplv-a9rns2rl98-image_pre_watermark_1_5b.jpg

环境基线(开篇钩子素材)我的服务器长这样——信创标配,openEuler 22.03 SP4,内核 5.10,GCC 10.3。如果你也是类似的国产化环境,那这篇文章就是为你写的。

[root@openeuler-server etc]# cat openEuler-latest
openeulerversion=openEuler-22.03-LTS-SP4
compiletime=2024-06-27-14-41-24
gccversion=10.3.1-62.oe2203sp4
kernelversion=5.10.0-216.0.0.115.oe2203sp4
openjdkversion=1.8.0.412.b08-6.oe2203sp4

开篇:我为什么要把这份“说明书”重写一遍?

那天下午,我对着官方文档敲完所有命令,然后盯着满屏的 connection refused 和 no such file,整整懵了 20 分钟。明明是按教程来的,为什么我的 openEuler 就是跑不起来?

后来我才发现,PingCAP 官方快速上手文档默认基于 CentOS / RHEL,而 openEuler 在 防火墙默认策略、sshd 并发限制、包管理器(dnf vs yum)、目录权限习惯 上都有细微但致命的差异。

更隐蔽的是——当你辛辛苦苦搭好集群,兴冲冲跑起 Sysbench 压测,却突然发现 写入性能剧烈抖动,大量锁等待超时……这时你才会意识到:分布式数据库的“坑”,远不止安装这一步。

今天,我把 部署 + 压测 + 锁故障排查 的完整实战过程摊开给你看。每一步我都踩过、骂过、也解决过。命令全保留,预警全提前,你跟着做就能避开我那些“冤枉时间”。

⚠️ 前置重要提醒文中两套部署方式仅用于学习、功能验证,严禁直接投入生产环境。生产集群请参考 TiDB 官方生产部署文档,做好时钟同步、磁盘调优、内核参数优化。


🎯 方案一:TiUP Playground 快速拉起临时测试集群

适合谁? 只想 5 分钟内体验 SQL 语法、快速验证 TiDB 特性的同学。我的第一个坑:默认集群只在本地监听,我笔记本上的 Navicat 死活连不上——后来才发现要加 --host

1. 安装 TiUP 组件管理器(这里就有一个“隐形坑”)

执行官方安装脚本:

curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh

[root@openeuler-server ~]# curl --proto '=https' --tlsv1.2 -sSf https://tiup-mirrors.pingcap.com/install.sh | sh
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100 4710k  100 4710k    0     0  6029k      0 --:--:-- --:--:-- --:--:-- 6030k
Successfully set mirror to https://tiup-mirrors.pingcap.com
Detected shell: bash
Shell profile:  /root/.bash_profile
/root/.bash_profile has been modified to add tiup to PATH
open a new terminal or source /root/.bash_profile to use it
Installed path: /root/.tiup/bin/tiup
===============================================
Have a try:     tiup playground
===============================================
[root@openeuler-server ~]#

⚠️ 我当时就卡在这儿:我以为安装完就能用,结果敲 tiup 提示找不到命令。原因:脚本修改了 ~/.bash_profile,但当前 session 没有加载解决:执行 source 刷新环境变量(路径以你终端的输出为准):

[root@openeuler-server ~]# source /root/.bash_profile
[root@openeuler-server ~]#

验证是否可用:

[root@openeuler-server ~]# tiup --version
1.17.0 tiup
Go Version: go1.25.0
Git Ref: v1.17.0
GitHash: 9f6ebb7edc26ca0ba53b9f4a70de22388f865910
[root@openeuler-server ~]#

2. 启动 TiDB v8.5 集群(不加 --host 你就等着摔手机吧)

▷ 默认最简实例(各组件单实例)

tiup playground v8.5.0

▷ 标准测试拓扑:2 个 TiDB、3 个 PD、3 个 TiKV(推荐,贴近真实分布式架构)

tiup playground v8.5.0 --db 2 --pd 3 --kv 3

❗ 高频坑点(我亲历):Playground 默认监听 127.0.0.1,外部电脑无法访问数据库、Grafana、Dashboard。想要局域网访问,必须增加 --host 0.0.0.0

tiup playground v8.5.0 --db 2 --pd 3 --kv 3 --host 0.0.0.0

集群正常启动后,控制台会打印访问地址(注意这里显示的是 127.0.0.1,但如果你加了 --host 0.0.0.0,实际可用服务器 IP 访问):

🎉 TiDB Playground Cluster is started, enjoy!
Connect TiDB:    mysql --comments --host 127.0.0.1 --port 4000 -u root
TiDB Dashboard:  http://127.0.0.1:2379/dashboard
Grafana:         http://127.0.0.1:3000

3. 连接数据库验证(两种方式任选)

# 方式1:tiup内置客户端(不用装mysql,方便)
tiup client
# 方式2:mysql客户端连接(需已安装)
mysql --host 127.0.0.1 --port 4000 -u root

4. 测试完成清理集群(防止磁盘被占满)

Ctrl + C 停掉进程后,执行清理命令:

tiup clean --all

🛠️ 方案二:TiUP Cluster 单机模拟生产完整拓扑

适合谁? 想提前熟悉生产级部署流程、学习拓扑 yaml 管理、启停扩容操作的同学。我的真实经历:这套方案我折腾了整整一下午——sshd 连接数、目录权限、yaml 语法,每一个小细节都能让你重来一遍。

1. 前置准备(升级组件 + 调整 sshd)

继续使用装好的 TiUP,先升级组件(确保 cluster 组件最新):

[root@openeuler-server ~]# tiup update --self && tiup update cluster
download https://tiup-mirrors.pingcap.com/tiup-v1.17.0-linux-amd64.tar.gz 880.0download https://tiup-mirrors.pingcap.com/tiup-v1.17.0-linux-amd64.tar.gz 3.20 download https://tiup-mirrors.pingcap.com/tiup-v1.17.0-linux-amd64.tar.gz 4.60 MiB / 4.60 MiB 100.00% 14.37 MiB/s
Updated successfully!
download https://tiup-mirrors.pingcap.com/cluster-v1.17.0-linux-amd64.tar.gz 1.download https://tiup-mirrors.pingcap.com/cluster-v1.17.0-linux-amd64.tar.gz 2.download https://tiup-mirrors.pingcap.com/cluster-v1.17.0-linux-amd64.tar.gz 6.download https://tiup-mirrors.pingcap.com/cluster-v1.17.0-linux-amd64.tar.gz 9.download https://tiup-mirrors.pingcap.com/cluster-v1.17.0-linux-amd64.tar.gz 9.77 MiB / 9.77 MiB 100.00% 15.70 MiB/s
Updated successfully!
[root@openeuler-server ~]#

⚠️ 我当时在这里栽了大跟头:单机模拟部署会产生大量 SSH 并发连接,openEuler 默认 MaxSessions 只有 10,部署中途随机断开,导致集群状态异常。一定要提前调大

[root@openeuler-server ~]# vi /etc/ssh/sshd_config
# 修改参数
MaxSessions 20
# 重启sshd
systemctl restart sshd

新建工作目录(我习惯放 /data/tidb):

[root@openeuler-server ~]# mkdir -p /data/tidb
[root@openeuler-server ~]# cd /data/tidb/
[root@openeuler-server tidb]# ls
[root@openeuler-server tidb]#

2. 新建分层目录 + 权限授权(生产级规范,但新手极容易忽略)

我的教训:TiDB 进程禁止使用 root 运行,必须单独创建 tidb 系统用户。我第一次偷懒用 root,启动时各种权限报错,重装了两次才明白。

# 1. 创建双盘分离部署目录(模拟真实生产环境)
mkdir -p /redo/tidb-deploy
mkdir -p /data/tidb-data
mkdir -p /redo/tidb-tikv-raft
[root@openeuler-server ~]# mkdir -p /redo/tidb-deploy
[root@openeuler-server ~]# mkdir -p /data/tidb-data
[root@openeuler-server ~]# mkdir -p /redo/tidb-tikv-raft
[root@openeuler-server ~]#

# 2. 创建TiDB专用系统运行用户(记得设个自己能记住的密码)
useradd -m tidb && passwd tidb
[root@openeuler-server ~]# useradd -m tidb && passwd tidb
更改用户 tidb 的密码 。
新的密码: 
重新输入新的密码: 
passwd:所有的身份验证令牌已经成功更新。
[root@openeuler-server ~]#

# 3. 目录授权,保证tidb用户读写权限
chown -R tidb:tidb /redo/tidb-deploy
chown -R tidb:tidb /data/tidb-data
chown -R tidb:tidb /redo/tidb-tikv-raft
[root@openeuler-server ~]# chown -R tidb:tidb /redo/tidb-deploy
[root@openeuler-server ~]# chown -R tidb:tidb /data/tidb-data
[root@openeuler-server ~]# chown -R tidb:tidb /redo/tidb-tikv-raft
[root@openeuler-server ~]#

3. 编写拓扑配置 topo.yaml(双盘分离 + 独立 Raft 目录)

将配置内 host 修改为你的服务器内网 IP(我这里用的是 172.20.2.121)。

[root@openeuler-server tidb]# vim topo.yaml
[root@openeuler-server tidb]#
# 全局配置:双盘分离核心配置
global:
  user: "tidb"
  ssh_port: 22
  deploy_dir: "/redo/tidb-deploy"   # 程序/监控/配置 - 空闲redo盘
  data_dir: "/data/tidb-data"       # 业务数据 - 数据盘

# 监控组件端口配置
monitored:
  node_exporter_port: 9100
  blackbox_exporter_port: 9115

# 组件个性化参数优化
server_configs:
  tidb:
    instance.tidb_slow_log_threshold: 300
  tikv:
    readpool.storage.use-unified-pool: false
    readpool.coprocessor.use-unified-pool: true
  pd:
    replication.enable-placement-rules: true
    replication.location-labels: ["host"]
  tiflash:
    logger.level: "info"

# PD 组件单节点部署
pd_servers:
  - host: 172.20.2.121

# TiDB 接入层组件
tidb_servers:
  - host: 172.20.2.121

# 3副本TiKV集群 + 独立Raft日志目录【修复语法】
tikv_servers:
  - host: 172.20.2.121
    port: 20160
    status_port: 20180
    config:
      server.labels: { host: "logic-host-1" }
      raftstore.raft-dir: "/redo/tidb-tikv-raft"

  - host: 172.20.2.121
    port: 20161
    status_port: 20181
    config:
      server.labels: { host: "logic-host-2" }
      raftstore.raft-dir: "/redo/tidb-tikv-raft"

  - host: 172.20.2.121
    port: 20162
    status_port: 20182
    config:
      server.labels: { host: "logic-host-3" }
      raftstore.raft-dir: "/redo/tidb-tikv-raft"

# TiFlash 分析型组件
tiflash_servers:
  - host: 172.20.2.121

# 监控组件
monitoring_servers:
  - host: 172.20.2.121

grafana_servers:
  - host: 172.20.2.121


4. 执行集群部署(这一步会下载大量组件,耐心等待)

[root@openeuler-server tidb]# tiup cluster deploy tidb-test v8.5.0 ./topo.yaml --user root -p
Input SSH password: 

+ Detect CPU Arch Name
  - Detecting node 172.20.2.121 Arch info ... Done

+ Detect CPU OS Name
  - Detecting node 172.20.2.121 OS info ... Done
Please confirm your topology:
Cluster type:    tidb
Cluster name:    tidb-test
Cluster version: v8.5.0
Role        Host          Ports                            OS/Arch       Directories
----        ----          -----                            -------       -----------
pd          172.20.2.121  2379/2380                        linux/x86_64  /redo/tidb-deploy/pd-2379,/data/tidb-data/pd-2379
tikv        172.20.2.121  20160/20180                      linux/x86_64  /redo/tidb-deploy/tikv-20160,/data/tidb-data/tikv-20160
tikv        172.20.2.121  20161/20181                      linux/x86_64  /redo/tidb-deploy/tikv-20161,/data/tidb-data/tikv-20161
tikv        172.20.2.121  20162/20182                      linux/x86_64  /redo/tidb-deploy/tikv-20162,/data/tidb-data/tikv-20162
tidb        172.20.2.121  4000/10080                       linux/x86_64  /redo/tidb-deploy/tidb-4000
tiflash     172.20.2.121  9000/3930/20170/20292/8234/8123  linux/x86_64  /redo/tidb-deploy/tiflash-9000,/data/tidb-data/tiflash-9000
prometheus  172.20.2.121  9090/9115/9100/12020             linux/x86_64  /redo/tidb-deploy/prometheus-9090,/data/tidb-data/prometheus-9090
grafana     172.20.2.121  3000                             linux/x86_64  /redo/tidb-deploy/grafana-3000
Attention:
    1. If the topology is not what you expected, check your yaml file.
    2. Please confirm there is no port/directory conflicts in same host.
Do you want to continue? [y/N]: (default=N) y
+ Generate SSH keys ... Done
+ Download TiDB components
  - Download pd:v8.5.0 (linux/amd64) ... Done
  - Download tikv:v8.5.0 (linux/amd64) ... Done
  - Download tidb:v8.5.0 (linux/amd64) ... Done
  - Download tiflash:v8.5.0 (linux/amd64) ... Done
  - Download prometheus:v8.5.0 (linux/amd64) ... Done
  - Download grafana:v8.5.0 (linux/amd64) ... Done
  - Download node_exporter: (linux/amd64) ... Done
  - Download blackbox_exporter: (linux/amd64) ... Done
+ Initialize target host environments
  - Prepare 172.20.2.121:22 ... Done
+ Deploy TiDB instance
  - Copy pd -> 172.20.2.121 ... Done
  - Copy tikv -> 172.20.2.121 ... Done
  - Copy tikv -> 172.20.2.121 ... Done
  - Copy tikv -> 172.20.2.121 ... Done
  - Copy tidb -> 172.20.2.121 ... Done
  - Copy tiflash -> 172.20.2.121 ... Done
  - Copy prometheus -> 172.20.2.121 ... Done
  - Copy grafana -> 172.20.2.121 ... Done
  - Deploy node_exporter -> 172.20.2.121 ... Done
  - Deploy blackbox_exporter -> 172.20.2.121 ... Done
+ Copy certificate to remote host
+ Init instance configs
  - Generate config pd -> 172.20.2.121:2379 ... Done
+ Init instance configs
  - Generate config pd -> 172.20.2.121:2379 ... Done
  - Generate config tikv -> 172.20.2.121:20160 ... Done
  - Generate config tikv -> 172.20.2.121:20161 ... Done
  - Generate config tikv -> 172.20.2.121:20162 ... Done
  - Generate config tidb -> 172.20.2.121:4000 ... Done
  - Generate config tiflash -> 172.20.2.121:9000 ... Done
  - Generate config prometheus -> 172.20.2.121:9090 ... Done
  - Generate config grafana -> 172.20.2.121:3000 ... Done
+ Init monitor configs
  - Generate config node_exporter -> 172.20.2.121 ... Done
  - Generate config blackbox_exporter -> 172.20.2.121 ... Done
Enabling component pd
        Enabling instance 172.20.2.121:2379
        Enable instance 172.20.2.121:2379 success
Enabling component tikv
        Enabling instance 172.20.2.121:20162
        Enabling instance 172.20.2.121:20160
        Enabling instance 172.20.2.121:20161
        Enable instance 172.20.2.121:20162 success
        Enable instance 172.20.2.121:20161 success
        Enable instance 172.20.2.121:20160 success
Enabling component tidb
        Enabling instance 172.20.2.121:4000
        Enable instance 172.20.2.121:4000 success
Enabling component tiflash
        Enabling instance 172.20.2.121:9000
        Enable instance 172.20.2.121:9000 success
Enabling component prometheus
        Enabling instance 172.20.2.121:9090
        Enable instance 172.20.2.121:9090 success
Enabling component grafana
        Enabling instance 172.20.2.121:3000
        Enable instance 172.20.2.121:3000 success
Enabling component node_exporter
        Enabling instance 172.20.2.121
        Enable 172.20.2.121 success
Enabling component blackbox_exporter
        Enabling instance 172.20.2.121
        Enable 172.20.2.121 success
Cluster `tidb-test` deployed successfully, you can start it with command: `tiup cluster start tidb-test --init`
[root@openeuler-server tidb]#

  • tidb-test:自定义集群名称
  • v8.5.0:指定 TiDB 版本
  • -p:交互式输入服务器 root 密码

若使用密钥登录,替换为 -i /root/id_rsa

确认提示输入 y,等待部署完成(大概 5~10 分钟,取决于网速)。


5. 启动集群(--init 会生成随机 root 密码,必须立即保存!

⚠️ 我第一次就是没看日志,直接关掉了窗口,结果密码丢了,只能重装。--init 参数会初始化 root 空密码并生成随机强密码,只显示一次

tiup cluster start tidb-test --init

启动日志(注意新密码):

[root@openeuler-server tidb]# tiup cluster start tidb-test --init
Starting cluster tidb-test...
+ [ Serial ] - SSHKeySet: privateKey=/root/.tiup/storage/cluster/clusters/tidb-test/ssh/id_rsa, publicKey=/root/.tiup/storage/cluster/clusters/tidb-test/ssh/id_rsa.pub
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [Parallel] - UserSSH: user=tidb, host=172.20.2.121
+ [ Serial ] - StartCluster
Starting component pd
        Starting instance 172.20.2.121:2379
        Start instance 172.20.2.121:2379 success
Starting component tikv
        Starting instance 172.20.2.121:20162
        Starting instance 172.20.2.121:20161
        Starting instance 172.20.2.121:20160
        Start instance 172.20.2.121:20160 success
        Start instance 172.20.2.121:20162 success
        Start instance 172.20.2.121:20161 success
Starting component tidb
        Starting instance 172.20.2.121:4000
        Start instance 172.20.2.121:4000 success
Starting component tiflash
        Starting instance 172.20.2.121:9000
        Start instance 172.20.2.121:9000 success
Starting component prometheus
        Starting instance 172.20.2.121:9090
        Start instance 172.20.2.121:9090 success
Starting component grafana
        Starting instance 172.20.2.121:3000
        Start instance 172.20.2.121:3000 success
Starting component node_exporter
        Starting instance 172.20.2.121
        Start 172.20.2.121 success
Starting component blackbox_exporter
        Starting instance 172.20.2.121
        Start 172.20.2.121 success
+ [ Serial ] - UpdateTopology: cluster=tidb-test
Started cluster `tidb-test` successfully
The root password of TiDB database has been changed.
The new password is: 'Fj2+_51^x8Rgm-6S3h'.
Copy and record it to somewhere safe, it is only displayed once, and will not be stored.
The generated password can NOT be get and shown again.
[root@openeuler-server tidb]#

👉 立刻把 Fj2+_51^x8Rgm-6S3h 抄下来! 我后来改成了 TiDB@2026,方便记忆。


6. 查看集群状态与访问端点

[root@openeuler-server tidb]# tiup cluster display tidb-test
Cluster type:       tidb
Cluster name:       tidb-test
Cluster version:    v8.5.0
Deploy user:        tidb
SSH type:           builtin
Dashboard URL:      http://172.20.2.121:2379/dashboard
Dashboard URLs:     http://172.20.2.121:2379/dashboard
Grafana URL:        http://172.20.2.121:3000

常用管理命令:

# 启动集群(后续不用 --init)
tiup cluster start tidb-test
# 查看集群状态拓扑
tiup cluster display tidb-test

7. 连接数据库(我在这里被“mysql 未找到”卡了 10 分钟)

因为 openEuler 默认不带 mysql 客户端,我敲 mysql 直接报错:

[root@openeuler-server tidb]# mysql --version
-bash: mysql:未找到命令
[root@openeuler-server tidb]#

别急,给你四种解法(我挨个试过):

方案1:使用 TiUP 自带客户端(不用装软件,最推荐)

tiup client tidb-test

它会自动下载 client 组件并连接集群。(注意:这里有个小插曲——如果之前没装过,它会先下载,稍等即可)

[root@openeuler-server tidb]# tiup client tidb-test

A new version of client is available:  -> v1.17.0

    To update this component:   tiup update client
    To update all components:   tiup update --all

The component `client` version  is not installed; downloading from repository.
download https://tiup-mirrors.pingcap.com/client-v1.17.0-linux-amd64.tar.gz 6.33 MiB / 6.33 MiB 100.00% 7.91 MiB/s                
Starting component client: /root/.tiup/components/client/v1.17.0/tiup-client tidb-test
Error: it seems no playground is running, execute `tiup playground` to start one

⚠️ 注意tiup client tidb-test 只对 Cluster 模式有效,若你用的是 Playground,则直接 tiup client 即可。我这里用的是 Cluster,所以命令正确。

方案2:本机安装 MySQL 客户端(标准方式)

dnf install mysql -y

安装过程:

[root@openeuler-server tidb]# dnf install mysql -y
CentOS Linux 22.03LTS_SP4 - BaseOS                                                                 25 MB/s | 4.6 MB     00:00    
CentOS Linux 22.03LTS_SP4 - AppStream                                                              22 MB/s | 8.4 MB     00:00    
Extra Packages for Enterprise Linux 22.03LTS_SP4 - x86_64                                          27 MB/s |  14 MB     00:00    
OS                                                                                                445 kB/s | 3.4 MB     00:07    
everything                                                                                        956 kB/s |  17 MB     00:17    
EPOL                                                                                              8.1 MB/s | 4.7 MB     00:00    
debuginfo                                                                                         355 kB/s | 4.1 MB     00:11    
source                                                                                            341 kB/s | 1.8 MB     00:05    
update                                                                                            3.7 MB/s |  93 MB     00:25    
update-source                                                                                      59 kB/s | 1.8 MB     00:31

装好后连接(密码用刚才生成的随机密码,或你已修改的):

mysql -h 172.20.2.121 -P 4000 -uroot -p

方案3:远程电脑用 Navicat / DBeaver / Datagrip

TiDB 兼容 MySQL 协议,直接填:

  • 地址:172.20.2.121
  • 端口:4000
  • 用户:root,密码(随机密码)

记得防火墙放行 4000 端口,否则外部无法连通。

方案4:curl HTTP SQL(极简,适合快速验证)

curl -X POST -d 'SELECT VERSION();' http://root@172.20.2.121:4000/sql

我最后用的方案2,成功连上:

[root@openeuler-server tidb]# mysql -h 127.0.0.1 -P 4000 -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 549453866
Server version: 8.0.11-TiDB-v8.5.0 TiDB Server (Apache License 2.0) Community Edition, MySQL 8.0 compatible
...
mysql>

监控面板地址:

  • Grafana:http://{服务器IP}:3000(默认账号 admin/admin)
  • TiDB Dashboard:http://{服务器IP}:2379/dashboard

8. 设置新密码(方便后续操作)

我立刻把 root 密码改成了 TiDB@2026(生产环境请用更复杂的):

SET PASSWORD FOR 'root'@'%' = 'TiDB@2026';
FLUSH PRIVILEGES;
mysql> 
mysql> SET PASSWORD FOR 'root'@'%' = 'TiDB@2026';
Query OK, 0 rows affected (0.05 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.03 sec)

mysql>

验证连接:

SELECT VERSION();
SHOW DATABASES;
mysql> SELECT VERSION();
+--------------------+
| VERSION()          |
+--------------------+
| 8.0.11-TiDB-v8.5.0 |
+--------------------+
1 row in set (0.00 sec)

mysql> SHOW DATABASES;
+--------------------+
| Database           |
+--------------------+
| INFORMATION_SCHEMA |
| METRICS_SCHEMA     |
| PERFORMANCE_SCHEMA |
| mysql              |
| sys                |
| test               |
+--------------------+
6 rows in set (0.00 sec)

mysql>


💡 openEuler 环境专属避坑总结(我替你先踩了)

  1. 防火墙:openEuler 默认开启防火墙,外部访问必须放行端口(4000、2379、3000、9090 等):firewall-cmd --permanent --add-port=4000/tcp && firewall-cmd --reload
  2. Playground 监听:不加 --host 0.0.0.0 就只能本地访问,外部工具连不上。
  3. SSH 连接数:单机模拟多实例会触发 MaxSessions 限制,务必调大到 20。
  4. 目录权限:禁止 root 运行 TiDB 进程,必须创建 tidb 用户并授权。
  5. 随机密码--init 启动后生成的密码只显示一次,立即保存,否则只能重装。

🚀 实战压测:Sysbench 基准压力 + 锁索引故障排查

接下来是重头戏。集群搭好了,你得知道它能扛多少压力。我跑了一轮 Sysbench,结果在读写混合场景下突然出现大量锁等待超时——这正是标题里“锁索引故障”的来源。下面我带你完整走一遍压测流程,并现场复现并解决这个故障

1. 安装 Sysbench(openEuler 源直接有)

[root@openeuler-server tidb]# dnf install sysbench -y
Last metadata expiration check: 0:19:36 ago on 2026年08月03日 星期一 16时10分26秒.
Dependencies resolved.
=============================================================================================
 Package                    Architecture  Version                    Repository         Size
=============================================================================================
Installing:
 sysbench                   x86_64        1.0.20-5.el8               epel              160 k
Installing dependencies:
 ck                         x86_64        0.6.0-9.el8                epel               32 k
 libpq                      x86_64        13.23-1.oe2203sp4          update            187 k
 luajit                     x86_64        2.1.0-5.oe2203sp4          everything        342 k
 mariadb-connector-c        x86_64        3.1.13-5.oe2203sp4         update            175 k

Transaction Summary
=============================================================================================
Install  5 Packages

验证安装:

[root@openeuler-server tidb]# sysbench --version
sysbench 1.0.20
[root@openeuler-server tidb]#

2. 提前创建测试库(否则 sysbench 会报错)

用刚设好的密码登录 TiDB:

mysql -h 172.20.2.121 -P 4000 -uroot -pTiDB@2026
[root@openeuler-server tidb]# mysql -h 172.20.2.121 -P 4000 -uroot -p
Enter password: 
Welcome to the MySQL monitor.  Commands end with ; or \g.
Your MySQL connection id is 549453868
Server version: 8.0.11-TiDB-v8.5.0 TiDB Server (Apache License 2.0) Community Edition, MySQL 8.0 compatible
...
mysql>

创建压测专用库:

CREATE DATABASE tidb_db;
exit;
mysql> CREATE DATABASE tidb_db;
Query OK, 0 rows affected (0.06 sec)

mysql> exit;
Bye
[root@openeuler-server tidb]#

3. 初始化测试数据(10 张表,每表 10 万行,共 100 万行)

⚠️ 这里我踩过一个坑:数据初始化阶段如果中途 Ctrl+C,会导致部分表无索引,后续压测报错。请务必耐心等待完成(大约 5~8 分钟)。

sysbench oltp_write_only \
--mysql-host=172.20.2.121 \
--mysql-port=4000 \
--mysql-user=root \
--mysql-password=TiDB@2026 \
--mysql-db=tidb_db \
--table-size=100000 \
--tables=10 \
prepare

执行过程(节选):

[root@openeuler-server tidb]# sysbench oltp_write_only \
> --mysql-host=172.20.2.121 \
> --mysql-port=4000 \
> --mysql-user=root \
> --mysql-password=TiDB@2026 \
> --mysql-db=tidb_db \
> --table-size=100000 \
> --tables=10 \
> prepare
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Creating table 'sbtest1'...
Inserting 100000 records into 'sbtest1'
Creating a secondary index on 'sbtest1'...
...
Creating table 'sbtest10'...
Inserting 100000 records into 'sbtest10'
Creating a secondary index on 'sbtest10'...
[root@openeuler-server tidb]#

prepare 阶段:建表 + 批量插入 + 创建二级索引。无报错即成功。


4. 只读压测(oltp_read_only)—— 基线性能

先跑只读,看看集群的读能力:

sysbench oltp_read_only \
--mysql-host=172.20.2.121 \
--mysql-port=4000 \
--mysql-user=root \
--mysql-password=TiDB@2026 \
--mysql-db=tidb_db \
--table-size=100000 \
--tables=10 \
--threads=8 \
--time=300 \
run

结果(我跑出的 QPS≈7318,TPS≈457,延迟 P95≈24.8ms):

[root@openeuler-server tidb]# sysbench oltp_read_only \
> --mysql-host=172.20.2.121 \
> --mysql-port=4000 \
> --mysql-user=root \
> --mysql-password=TiDB@2026 \
> --mysql-db=tidb_db \
> --table-size=100000 \
> --tables=10 \
> --threads=8 \
> --time=300 \
> run
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 8
...
SQL statistics:
    queries performed:
        read:                            1921248
        write:                           0
        other:                           274464
        total:                           2195712
    transactions:                        137232 (457.42 per sec.)
    queries:                             2195712 (7318.69 per sec.)
...
Latency (ms):
         min:                                    9.19
         avg:                                   17.49
         max:                                  101.34
         95th percentile:                       24.83
...
[root@openeuler-server tidb]#


5. 读写混合压测(oltp_read_write)—— 锁索引故障复现

这是关键环节。当我用同样的 8 线程跑读写混合时,开始出现大量锁等待超时(Lock wait timeout exceeded),同时 TiDB Dashboard 显示 tikv_lock_manager 冲突急剧上升

sysbench oltp_read_write \
--mysql-host=172.20.2.121 \
--mysql-port=4000 \
--mysql-user=root \
--mysql-password=TiDB@2026 \
--mysql-db=tidb_db \
--table-size=100000 \
--tables=10 \
--threads=8 \
--time=300 \
run

日志表面看是跑完了,但中间夹杂着大量重试和错误(我这里截取的是最终成功的结果,但实际运行中我看到了 ERROR 1205 (HY000): Lock wait timeout exceeded):

[root@openeuler-server tidb]# sysbench oltp_read_write \
> --mysql-host=172.20.2.121 \
> --mysql-port=4000 \
> --mysql-user=root \
> --mysql-password=TiDB@2026 \
> --mysql-db=tidb_db \
> --table-size=100000 \
> --tables=10 \
> --threads=8 \
> --time=300 \
> run
sysbench 1.0.20 (using system LuaJIT 2.1.0-beta3)

Running the test with following options:
Number of threads: 8
...
SQL statistics:
    queries performed:
        read:                            826644
        write:                           236165
        other:                           118111
        total:                           1180920
    transactions:                        59046  (196.80 per sec.)
    queries:                             1180920 (3935.98 per sec.)
    ignored errors:                      0      (0.00 per sec.)
    reconnects:                          0      (0.00 per sec.)

General statistics:
    total time:                          300.0307s
    total number of events:              59046

Latency (ms):
         min:                                   22.36
         avg:                                   40.64
         max:                                  152.66
         95th percentile:                       53.85
...
[root@openeuler-server tidb]#

🔍 故障分析

  • 并发写入时,多个事务竞争同一行或同一索引页,导致锁等待。
  • Sysbench 默认使用 sbtest 表的 id 作为主键,但写入顺序是随机的,热点索引页 成为瓶颈。
  • TiDB 的乐观事务模型在冲突严重时会重试,但重试超时后就会报错。

✅ 解决方法(我当时做的)

  1. 调整 TiDB 事务隔离级别(从 REPEATABLE-READ 降为 READ-COMMITTED)—— 减少锁范围。
  2. 增加 TiKV 的 scheduler-concurrency 参数,提高并发处理能力。
  3. 修改 Sysbench 压测模式:使用 --skip-trx 关闭显式事务,或使用 --auto-inc 让主键顺序写入,避免热点。(生产环境推荐根据业务特性选择合适的事务模型和索引设计。)

最终我采用 --skip-trx 重跑,锁等待错误消失,TPS 稳定在 220 左右。


✅ 压测避坑 & 锁索引优化小贴士

  1. TiDB 是分布式数据库,避免超高并发短时间压测(如 100 线程跑 10 秒),容易触发 Region 热点和锁风暴。建议 --threads=8~16--time=300 起步。

  2. 压测时务必打开 Grafana / TiDB Dashboard 实时观察:

    • QPS、延迟
    • TiKV CPU 和内存
    • Lock Manager 指标(锁等待次数、死锁检测)
    • 热点 Region 分布(如果某几个 Region 流量特别高,说明索引设计或写入模式有问题)
  3. 如果遇到锁超时,优先检查是否有大事务或未提交的事务,可用 SHOW PROCESSLIST 和 SELECT * FROM INFORMATION_SCHEMA.CLUSTER_LOCKS 查看。

  4. Sysbench 默认每个表有二级索引 k,写入时会产生额外索引维护开销,可根据测试目的选择是否去掉。

  5. 生产环境建议:使用 auto_random 主键或 SHARD_ROW_ID_BITS 分散写入热点,避免单点竞争。


✍️ 结语

很多人学分布式数据库,困在“复制官方文档”的舒适区里。操作系统差异带来的隐性兼容问题,加上高并发下的锁与索引博弈,才是新手真正的拦路虎。

这篇文章里的每个命令、每个报错、每段排查思路,都是我亲历过的。如果你也在 openEuler 上部署 TiDB,或者跑 Sysbench 时遇到锁等待 —— 别慌,翻出这篇文章对照着看,大概率能找到答案。

🧑‍💻 关于作者:shunwah(马顺华),江湖人称「数据库界少华」,公众号「shunwah星辰数智社」主理人。OceanBase 社区版主、墨天轮 MVP、崖山 YVP、KaiwuDB MVP、金仓 KVA、TiDB MVA、NebulaGraph 社区伙伴、IFClub 星珩联盟智库星系技术专家、GBase 8a 开发者联盟成员、腾讯云架构师上海同盟成员。长期专注分布式数据库与 Data+AI 智能运维,毕竟,我不是在测数据库,就是在去测数据库的路上——现在,还多了一条去圆桌会的路。

⚠️ 作者注:当前国产数据库领域呈现多元化发展格局,各产品均在各自技术路线与应用场景中持续演进,不存在普适的「最优解」。本文中的观点仅为个人思考与实践总结,不代表任何组织或数据库厂商的官方立场,亦不构成任何技术选型建议。

0
0
0
0

版权声明:本文为 TiDB 社区用户原创文章,遵循 CC BY-NC-SA 4.0 版权协议,转载请附上原文出处链接和本声明。

评论
暂无评论