当前位置: 首页 > news >正文

OceanBase DBA实战营2期--SQL 关键字限流学习笔记

1.SQL 关键字限流简介
SQL 限流是一种控制数据库并发访问的能力,当数据库面临大量并发请求时,可以通过限制某些 SQL 语句的执行数量来保护数据库资源。OceanBase 数据库支持关键字的 SQL 限流,能够在 SQL 语句进入数据库引擎之前就将其拦截,防止查询在并发时发生资源争抢。
简单来说,实现逻辑就是尽量在 SQL 引擎的更靠前的位置进行限流规则的匹配检查,最大程度阻止 SQL 进入后续的执行逻辑。限流规则检查时将遍历所有的限流规则,对所有满足的规则记录并发度+1,当满足任意一个限流规则上限时,报错退出。
2.OceanBase 关键字限流特性介绍
语法支持
创建 SQL 限流规则

当 SQL 请求数达到限流规则上限后,会抛出相关错误码到客户端。限流规则创建之后将立即生效
删除 SQL 限流规则

被删除的限流规则会立即失效。
权限管理
社区版的 MySQL 模式的租户,需要 user level 的 create 权限。

细节说明
限流规则名称不能超过 128 字节。
系统中限流规则个数目前无限制。
database name 和 tablename在MySQL模式下会受 lower_case table_names 变量的影响。
限流关键字:
● 关键字之间将用通配符%连接,例如给定3个关键词’asdasd’,‘c2= 123’xxyyzz’,其会被拼成’asdasdc2=123xxyyzz%‘,后续将按照这个字符串进行SQL 文本的通配匹配。
● 当关键字中有’时会被转义,如’table t1’会被记录成’&table\ t1%'限流关键字无个数限制,但限制拼凑后的字符串长度不能超过OB_MAX_VARCHAR_LENGTH=1048576 。
关键字字符串的字符集和字符序为 binary。
其中 MAX_CONCURRENCY=10指单机并发上限,即其为机器级而非集群级的。比如假设集群有3 台机器,那么指的是这三台机器各自的限流并发上限为 10。
per sql为可选的选项。表示限流规则的统计粒度,假设有限流规则ccl_1:

有如下请求:
● 如果没有 per sql,表示统计粒度为规则级别,那么sql-1和sq1-2将共同被 cc_1 限制执行的并发上限,同一时间全部 SQL 数量总计不能超过 10。
● 如果有 per sql,表示统计粒度为 Format SQLID 语句级别,那么 sq-1和sql-2 将各自被cC1 1 限制执行并发上限,同一时间每个 SQL 数量总计不能超过 10。
说明:
format_sal_id是创建 outline 时用到的,可以通过两种方式创建模糊 outline,一种是通过 format SQL TEXT(用户执行的带参数的原始语句),另一种是通过fommat_sql_id 创建。

需要用 outline 绑定的 SQL 时,对应的经过一些规则的改写得到的 format_stmt,然后系统会根据format_stmt 计算 md5 值得到的 format sal_id。format_sqli_d 可通过 GVSOB SQL_AUDIT 中获取。
作用范围
对于 multi statement 不生效。
说明:
multi statement 指将多条 SQL 语句合并为一个请求发送,例如:SELECT * FROM users; SELECT COUNT(*) FROM orders;数据库会依次执行这两条语句,并返回每个语句的结果
命中多条限流规则时的行为
一条 SQL 请求可能命中多条限流规则,此时每条限流规则都生效,属于 and 逻辑。
例如:
先加表级 select 单条并发限制 3,后加库级 select 全局并发限制 10000。

user1 对 db1.tbA 的每条查询语句,并发数都不能超过3;并且不能超过整体1万的并发限制,触达任意一个规则时都会报错
与 outline 限流的正交
当前 OceanBase 已有的 outline 限流与本期课程描述的关键字限流规则,属于并列关系。会按照 3.4 的规则与关键字限流规则一起生效。
用法举例

新增字典视图
可以通过字典视图DB_OB_CCL_RULES 来查询全部的限流规则。
。可以通过性能视图 GVOBSQLCCLSTATUS或VOB_SQL_CCL_STATUS或VOBSQLCCLSTATUSVOB_SQL_CCL_STATUS 来访问当前被限流的 SQL 与命中的限流规则,以及其这些规则剩余可用并发度,用于诊断。
3.实验过程
按照以下步骤,在 OceanBase 数据库 MySQL 模式下创建 SQL 限流规则:
– 创建测试表
CREATE TABLE test_table(id INT, name VARCHAR(50));

– 创建限流规则(示例:限制对 test_table 的查询并发数)
CREATE CONCURRENT_LIMITING_RULE IF NOT EXISTS test_limit_rule
ON test.test_table
TO ‘root’@‘%’
FOR SELECT
FILTER BY KEYWORD(‘test_table’)
WITH MAX_CONCURRENCY = 0;

– 查看限流规则
SELECT * FROM oceanbase.DBA_OB_CCL_RULES;

– 测试限流效果
SELECT COUNT(*) FROM test_table WHERE id = 123;

– 当触发限流规则时,会返回以下错误信息:
ERROR 11087 (HY000): SQL reach max ccl rule test_limit_rule, concurrent num 0

– 删除限流规则
DROP CONCURRENT_LIMITING_RULE IF EXISTS test_limit_rule;

实验过程如下:
连接数据库
在线环境中 root 用户未设置密码,仅供体验使用,在实际环境中,请根据需要配置相关用户密码。
在开始之前,请确保已连接到 OceanBase 数据库。如果尚未连接,可以使用以下命令:
[admin@xxx ~]obclient -h127.0.0.1 -P2881 -uroot@mysql_tenant -A -Dtest
创建数据表结构
电商平台在双十一等大促期间,数据库会面临巨大的访问压力。某些不重要的查询(如商品详情页的辅助信息查询)可能会消耗大量资源,影响核心交易流程。通过 SQL 关键字限流,可以在事前对这些查询进行限制,确保核心业务不受影响。
假设我们有一个电商数据库,包含以下核心表:
● orders:订单表(核心业务)
● products:商品表(核心业务)
● product_reviews:商品评论表(非核心业务)
● user_activities:用户行为表(非核心业务)
在大促期间,我们需要:

  1. 保护核心订单和商品查询
  2. 限制非核心业务的查询并发
  3. 设置应急限流机制
    创建表结构来存储业务数据:
    – 创建订单表
    CREATE TABLE orders (
    id BIGINT AUTO_INCREMENT PRIMARY KEY,
    user_id BIGINT,
    product_id BIGINT,
    quantity INT,
    total_amount DECIMAL(10,2),
    order_status ENUM(‘pending’, ‘paid’, ‘shipped’, ‘delivered’),
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
    );

– 创建商品表
CREATE TABLE products (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
product_name VARCHAR(255),
price DECIMAL(10,2),
stock INT,
category VARCHAR(100),
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

– 创建商品评论表(非核心业务)
CREATE TABLE product_reviews (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
product_id BIGINT,
user_id BIGINT,
rating INT,
comment TEXT,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

– 创建用户行为表(非核心业务)
CREATE TABLE user_activities (
id BIGINT AUTO_INCREMENT PRIMARY KEY,
user_id BIGINT,
activity_type VARCHAR(50),
activity_data JSON,
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

– 插入测试数据
INSERT INTO products (product_name, price, stock, category) VALUES
(‘iPhone 15’, 5999.00, 100, ‘Smartphone’),
(‘MacBook Pro’, 12999.00, 50, ‘Computer’),
(‘AirPods Pro’, 1999.00, 200, ‘Accessory’),
(‘iPad Air’, 3999.00, 80, ‘Tablet’);

INSERT INTO orders (user_id, product_id, quantity, total_amount, order_status) VALUES
(1001, 1, 1, 5999.00, ‘paid’),
(1002, 2, 1, 12999.00, ‘pending’),
(1003, 3, 2, 3998.00, ‘shipped’);

INSERT INTO product_reviews (product_id, user_id, rating, comment) VALUES
(1, 1001, 5, ‘Excellent smartphone’),
(1, 1002, 4, ‘Good value for money’),
(2, 1003, 5, ‘Powerful performance’);

INSERT INTO user_activities (user_id, activity_type, activity_data) VALUES
(1001, ‘view_product’, ‘{“product_id”: 1, “duration”: 30}’),
(1002, ‘search’, ‘{“keyword”: “iPhone”, “results”: 5}’),
(1003, ‘add_to_cart’, ‘{“product_id”: 3, “quantity”: 2}’);

配置限流策略
– 创建非核心业务限流规则
– 限制商品评论查询的并发数
CREATE CONCURRENT_LIMITING_RULE IF NOT EXISTS review_query_limit
ON test.product_reviews
TO ‘root’@‘%’
FOR SELECT
FILTER BY KEYWORD(‘product_reviews’)
WITH MAX_CONCURRENCY = 5;

– 限制用户行为查询的并发数
CREATE CONCURRENT_LIMITING_RULE IF NOT EXISTS activity_query_limit
ON test.user_activities
TO ‘root’@‘%’
FOR SELECT
FILTER BY KEYWORD(‘user_activities’)
WITH MAX_CONCURRENCY = 3;

– 创建全局应急限流规则(限制所有包含特定关键字的查询)
CREATE CONCURRENT_LIMITING_RULE IF NOT EXISTS emergency_limit
ON .
TO ‘root’@‘%’
FOR ALL
FILTER BY KEYWORD(‘product_reviews’, ‘user_activities’)
WITH MAX_CONCURRENCY = 1;

测试限流效果
核心业务查询测试限流效果
– 核心业务查询:商品信息查询(应该成功)
SELECT * FROM products WHERE id = 1;

– 核心业务查询:订单信息查询(应该成功)
SELECT * FROM orders WHERE user_id = 1001;
分别输出如下:
obclient [test]> SELECT * FROM products WHERE id = 1;
±—±-------------±--------±------±-----------±--------------------+
| id | product_name | price | stock | category | created_at |
±—±-------------±--------±------±-----------±--------------------+
| 1 | iPhone 15 | 5999.00 | 100 | Smartphone | 2025-08-20 15:26:47 |
±—±-------------±--------±------±-----------±--------------------+
1 row in set (0.059 sec)

obclient [test]> SELECT * FROM orders WHERE user_id = 1001;
±—±--------±-----------±---------±-------------±-------------±--------------------+
| id | user_id | product_id | quantity | total_amount | order_status | created_at |
±—±--------±-----------±---------±-------------±-------------±--------------------+
| 1 | 1001 | 1 | 1 | 5999.00 | paid | 2025-08-20 15:26:47 |
±—±--------±-----------±---------±-------------±-------------±--------------------+
1 row in set (0.008 sec)
非核心业务查询测试限流效果
在线实验环境中倒是没遇到被限流
– 非核心业务查询:商品评论统计(可能被限流)
SELECT COUNT(*) FROM product_reviews WHERE product_id = 1;

– 当触发限流规则时,会返回以下错误信息:
ERROR 11087 (HY000): SQL reach max ccl rule review_query_limit, concurrent num 5

– 非核心业务查询:用户行为统计(可能被限流)
SELECT COUNT(*) FROM user_activities WHERE user_id = 1001;

– 当触发限流规则时,会返回以下错误信息:
ERROR 11087 (HY000): SQL reach max ccl rule activity_query_limit, concurrent num 3

分析限流信息
– 查看所有限流规则
SELECT * FROM oceanbase.DBA_OB_CCL_RULES;

– 查看限流统计信息
– 记录当前被限流的 SQL 与命中的限流规则,以及这些规则剩余可用并发度
SELECT * FROM oceanbase.V$OB_SQL_CCL_STATUS;

– 查看被限流的 SQL 语句
SELECT * FROM oceanbase.V$OB_SQL_AUDIT WHERE CCL_RULE_ID != 0;

– 可能的返回结果如下:

±-----------±-----------------±-----------------±-----------------±-----------------±-----------------+
| SQL_ID | CCL_RULE_ID | CCL_RULE_NAME | SQL_TEXT | EXEC_TIME | STATUS |
±-----------±-----------------±-----------------±-----------------±-----------------±-----------------+
| 1234567890 | 1 | review_query_limit| SELECT COUNT() FROM product_reviews WHERE product_id = 1 | 2024-01-01 10:05:00 | THROTTLED |
| 1234567891 | 2 | activity_query_limit| SELECT COUNT(
) FROM user_activities WHERE user_id = 1001 | 2024-01-01 10:05:30 | THROTTLED |
±-----------±-----------------±-----------------±-----------------±-----------------±-----------------+
2 rows in set (0.001 sec)
清理环境
– 删除所有限流规则
DROP CONCURRENT_LIMITING_RULE IF EXISTS review_query_limit;
DROP CONCURRENT_LIMITING_RULE IF EXISTS activity_query_limit;
DROP CONCURRENT_LIMITING_RULE IF EXISTS emergency_limit;

– 删除测试表
DROP TABLE IF EXISTS user_activities;
DROP TABLE IF EXISTS product_reviews;
DROP TABLE IF EXISTS orders;
DROP TABLE IF EXISTS products;

http://www.dtcms.com/a/341638.html

相关文章:

  • ae复制合成后修改里面图层相互影响问题
  • uos(类linux)系统 打印机自定义打印尺寸
  • MySQL分库分表与MyCAT
  • open webui源码分析5-Tools
  • 基于单片机水质检测系统/污水监测系统/水情监测
  • ansible中roles角色是什么意思?
  • 详解flink table api基础(三)
  • 【网络】使用 DNAT 进行负载均衡时,若未配置配套的 SNAT,回包失败
  • 猫头虎开源AI分享|基于大模型和RAG的一款智能text2sql问答系统:SQLBot(SQL-RAG-QABot),可以帮你用自然语言查询数据库
  • Three.js 初级教程大全
  • 分享|财务大数据实验室建设方案
  • 机器学习(Machine Learning, ML)
  • Web网站的运行原理2
  • Ubuntu实现程序开机自动运行
  • AI每日需求进度分析总结(附实战操作)
  • 云原生环境下的ITSM新趋势:从传统运维到智能化服务管理
  • 政务网站与新媒体自查情况的报告怎么写?
  • 【ssh】ssh免密登录配置【docker】
  • STM32_0001 KEILMDK V5.36 编译一个STM32F103C8T6说core_cm3.h文件找不到以及编译器版本不匹配的解决办法
  • 25_基于深度学习的行人检测识别系统(yolo11、yolov8、yolov5+UI界面+Python项目源码+模型+标注好的数据集)
  • 详解ThreadLocal<HttpServletRequest> requestThreadLocal
  • Kernel Study
  • 关联规则挖掘1:Apriori算法
  • Deepresearch Agents:下一代自动研究智能体的架构革命与产业实践
  • CAMEL-Task1-CAMEL环境配置及你的第一个Agent
  • postgreSQL卸载踩坑
  • Kolors Virtual Try-On:快手可图推出的AI虚拟换衣项目
  • JAVA中向量数据库(Milvus)怎么配合大模型使用
  • 简笔成画:让AI绘画变得简单而有趣
  • pyecharts可视化图表仪表盘_Gauge:从入门到精通