Archery-SQL审核查询平台
Archery-SQL审核查询平台
文章目录
- Archery-SQL审核查询平台
- 一、功能列表介绍
- 1.1、SQL审核
- MySQL实例
- 非MySQL实例
- 审核执行分离
- SQL工单自动审批、高危语句驳回
- 快速上线其他实例
- 定时执行
- 1.2、SQL查询
- 多类型数据库支持
- 授权管理
- 页面体验
- 1.3、SQL优化
- 慢日志管理
- SQL语句优化
- 1.4、实例管理
- 会话管理
- 数据库管理
- 账号管理
- 参数配置
- 1.5、工具插件
- PTArchiver
- Binlog2SQL
- My2SQL
- SchemaSync
- 1.6、资源(项目)组
- 1.7、权限(角色)组
- 1.8、工作流
- 1.9、配置管理
- 1.10、消息通知
- 1.11、可视化
- 1.12、功能导图
- 二、部署
- 2.1、部署
- 2.1.1、安装docker版本18.09.9
- 2.1.2、安装docker-compose版本1.29.2
- 2.1.3、安装mysql
- 2.1.4、安装archery
- 2.2、系统配置
- 三、测试
- 3.1、增加资源组
- 3.2、新建实例
- 3.3、修改权限组
- 3.4、配置审批流程
- 3.5、修改新用户注册配置
- 3.6、创建各类型测试用户
- 3.7、创建上线sql/回滚
- 3.8、申请查询权限
- 3.9、申请归档权限
- 3.10、数据脱敏
- 脱敏规则配置
- 四、升级
- 4.1、执行数据库变更脚本(请注意数据备份)
- 4.2、更新服务
- 五、踩坑记录
- 5.1.执行上线sql时报错 lookup mysql on 127.0.0.11:53: no such host
- 5.2、执行上线SQL报错Execute: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation (sql: SHOW MASTER STATUS;).Execute: 无法获取master binlog信息.
Archery定位于SQL审核查询平台,旨在提升DBA的工作效率,支持多种数据库的SQL上线和查询,同时支持丰富的MySQL运维功能,所有功能都兼容手机端操作。
一、功能列表介绍
数据库 | 查询 | 审核 | 执行 | 备份 | 数据字典 | 慢日志 | 会话管理 | 账号管理 | 参数管理 | 数据归档 |
---|---|---|---|---|---|---|---|---|---|---|
MySQL | √ | √ | √ | √ | √ | √ | √ | √ | √ | √ |
MsSQL | √ | × | √ | × | √ | × | × | × | × | × |
Redis | √ | × | √ | × | × | × | × | × | × | × |
PgSQL | √ | × | √ | × | × | × | × | × | × | × |
Oracle | √ | √ | √ | √ | √ | × | × | × | × | × |
MongoDB | √ | √ | √ | × | × | × | × | × | × | × |
Phoenix | √ | × | √ | × | × | × | × | × | × | × |
ODPS | √ | × | × | × | × | × | × | × | × | × |
ClickHouse | √ | √ | √ | × | × | × | × | × | × | × |
1.1、SQL审核
MySQL实例
基于Inception/goInception实现,集成审核、执行、备份
非MySQL实例
支持提交和执行工单,依托工作流实现流程化管理
审核执行分离
审批和执行可以分配给不同的用户进行操作
SQL工单自动审批、高危语句驳回
- 支持正则判断工单是否需要人工审批,开启自动审批后,不在正则范围内的SQL语句无需审批,系统自动审核
- 自主控制SQL是否自动驳回,可自主配置对inception审核驳回的场景,支持警告驳回和异常驳回
快速上线其他实例
在工单详情可快速提交相同SQL内容到其他实例,可适用于test>beta>ga等多套环境维护的需求
定时执行
工单审核通过后可以选择定时执行或者立即执行
1.2、SQL查询
多类型数据库支持
- MySQL 表级授权、脱敏查询
- MsSQL 库级授权、脱敏查询
- Redis 库级授权
- PostgreSQL 库级授权、脱敏查询
- Oracle 库级授权、脱敏查询
- MongoDB 库级授权
- Phoenix 库级授权
- ODPS 库级授权
- ClickHouse 库级授权
授权管理
- 工作流控制SQL查询授权,支持库表级别的权限限制,以及授权时间,查询结果集的限制
- 支持部分语句的动态查询脱敏(有限的功能)
- 支持前台管理用户权限,对用户权限进行修改和维护
- 支持查询导出、查询日志审计
页面体验
- 库、表、字段补全提示
- 多结果级展示
- 表结构查看
1.3、SQL优化
慢日志管理
基于PT收集慢日志,需要单独部署
SQL语句优化
基于SQLAdvisor|SOAR|SQLTuning的全方位优化建议
1.4、实例管理
会话管理
- 支持查看和批量终止会话
- 支持查看事物、锁信息
数据库管理
管理实例数据库,支持添加
账号管理
管理实例账号,支持增加、授权、删除
参数配置
可修改实例动态参数并记录修改历史
1.5、工具插件
PTArchiver
支持使用pt-archiver归档MySQL数据,支持直接添加配置和由用户申请归档
Binlog2SQL
将Binlog2SQL模块可视化,从MySQL binlog解析出你要的SQL
My2SQL
My2SQL可视化,更高效地解析MySQL binlog,快速回滚
SchemaSync
对比不同数据库的Schema信息,输出修改语句和回滚语句,SchemaSync不仅限于表结构,它可以处理的对象还有:视图、事件、存储过程、函数、触发器、外键
1.6、资源(项目)组
支持自定义资源(项目)组,管理资源组和关联对象,资源组成员之间审批流程、实例配置、消息通知等资源隔离
1.7、权限(角色)组
权限可以分配给用户,也可以分配给权限组,支持对大多数操作进行限制,独立控制用户的审核、执行等操作权限
1.8、工作流
工作流审批流程支持多层级多用户,并且隔离资源组,不同资源组不同的工单类型可以配置不同的审批层级
1.9、配置管理
系统配置项、工作流审批流程可在前端页面动态修改,无需重启服务实时生效
1.10、消息通知
支持钉钉、企业微信、邮件通知,及时知晓工单状态变化
1.11、可视化
使用pyecharts实现工单、查询维度的可视化统计
1.12、功能导图
二、部署
2.1、部署
服务器信息
系统:centos7.9
内网ip:192.168.0.213
公网ip:121.37.17.85
2.1.1、安装docker版本18.09.9
# wget https://download.docker.com/linux/centos/docker-ce.repo #下载docker的yum源
# mv docker-ce.repo /etc/yum.repos.d
# yum -y install docker-ce-18.09.9
# docker -v
Docker version 20.10.6, build 370c289
# systemctl start docker
# systemctl enable docker # 修改docker的日志规则
# vim /etc/docker/daemon.json #docker18版本之后无效
{
"log-driver":"json-file","log-opts":{ "max-size" :"500m","max-file":"30"} #最大日志500m 最大保留个数30,一定删除注释
},
{"registry-mirrors":["https://docker.mirrors.ustc.edu.cn"]
}#修改docker的数据存储路径
# vim /usr/lib/systemd/system/docker.service
在ExecStart=/usr/bin/dockerd-current \ 下添加
--graph /opt/docker \ #docker存储路径
--registry-mirror=http://hub-mirror.c.163.com \ #加速地址
--registry-mirror=https://docker.mirrors.ustc.edu.cn \
--registry-mirror=https://p31wiatp.mirror.aliyuncs.com \
-H tcp://0.0.0.0:6935 -H unix://var/run/docker.sock #portainer可以检测到# systemctl daemon-reload
# systemctl restart docker
# docker info |grep Root #查看docker数据存储位置
Docker Root Dir: /opt/docker
# ss -ltnp |grep 6935
2.1.2、安装docker-compose版本1.29.2
#安装docker-compose
# curl -L "https://github.com/docker/compose/releases/download/1.29.2/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
# chmod +x /usr/local/bin/docker-compose
# ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
# docker-compose --version
docker-compose version 1.29.2, build 5becea4c
2.1.3、安装mysql
创建目录
# mkdir -p /opt/mysql_8_0_31/mysql/data
# mkdir -p /opt/mysql_8_0_31/mysql/sql
# cd /opt/mysql_8_0_31/
准备初始化sql
# vim /opt/mysql_8_0_31/mysql/sql/archery.sql
CREATE DATABASE `archery` CHARACTER SET 'utf8mb4' COLLATE 'utf8mb4_0900_ai_ci';create user 'archery'@'%' identified by 'Archeryweb%123' ;GRANT ALL on archery.* TO 'archery'@'%';GRANT REPLICATION SLAVE,REPLICATION CLIENT,Select,Process,Create,Update,Insert,Drop,DELETE ON *.*
TO 'archery'@'%';
# 特别注意Drop,DELETE权限,生产不允许授这个权限,但是没有Drop,DELETE权限不能执行一些回滚sql,请联系管理员手动执行回滚sqlflush privileges;
编写docker-compose文件
# pwd
/opt/mysql_8_0_31/
# vim docker-compose-mysql.yaml
version: '3.7'
services:mysql8_0_31:image: docker.io/mysql:8.0.31ports:- 3366:3306container_name: mysql8_0_31environment:- MYSQL_ROOT_PASSWORD=Archeryweb%123volumes:- ./mysql/data:/var/lib/mysql- ./mysql/sql/archery.sql:/docker-entrypoint-initdb.d/archery.sqlrestart: always
docker-compose启动mysql
# pwd
/opt/mysql_8_0_31/
# docker-compose -f docker-compose-mysql.yaml create #根据docker-compose文件创建容器及网络或存储卷
# docker-compose -f docker-compose-mysql.yaml up -d # 后台启动容器
2.1.4、安装archery
上传archery.tar.gz包
# pwd
/opt# ls
Archery.tar.gz containerd docker# 解压tar包
# tar xzvf Archery.tar.gz
# ls
Archery Archery.tar.gz containerd docker# 查看目录结构
# tree ./Archery #如果提示没有tree命令,请执行yum -y install treeArchery
├── archery
│ ├── docs.md
│ ├── downloads
│ │ ├── archiver
│ │ ├── binlog2sql
│ │ └── schemasync
│ ├── keys
│ ├── logs
│ │ ├── archery.log
│ │ ├── qcluster.log
│ │ └── supervisord.log
│ ├── notify.py
│ ├── notify.py.bak
│ ├── settings.py
│ ├── soar_path
│ │ ├── soar_path
│ │ └── sqladvisor_path
│ ├── soar.yaml
│ └── sql
│ └── migrations
│ ├── 0001_initial.py
│ ├── __init__.py
│ └── __pycache__
│ ├── 0001_initial.cpython-39.pyc
│ └── __init__.cpython-39.pyc
├── docker-compose.yml
├── inception
│ └── config.toml
└── mysql└── my.cnf
修改mysql连接为外置
修改docker-compose
# cd Archery
# pwd
/opt/Archery# vim docker-compose.yml
version: '3'services:redis:image: redis:5container_name: redisrestart: alwayscommand: redis-server --requirepass 123456expose:- "6379"#将mysql的注释掉# mysql:# image: mysql:5.7# container_name: mysql# restart: always# ports:# - "3306:3306"# volumes:# - "./mysql/my.cnf:/etc/mysql/my.cnf"# - "./mysql/datadir:/var/lib/mysql"# environment:# MYSQL_DATABASE: archery# MYSQL_ROOT_PASSWORD: 123456goinception:image: hanchuanchuan/goinceptioncontainer_name: goinceptionrestart: alwaysports:- "4000:4000"volumes:- "./inception/config.toml:/etc/config.toml"archery:image: hhyo/archery:v1.9.1container_name: archeryrestart: alwaysports:- "9123:9123"volumes:- "./archery/settings.py:/opt/archery/local_settings.py"- "./archery/soar.yaml:/etc/soar.yaml"- "./archery/docs.md:/opt/archery/docs/docs.md"- "./archery/notify.py:/opt/archery/sql/notify.py"- "./archery/downloads:/opt/archery/downloads"- "./archery/soar_path/sqladvisor_path:/opt/archery/soar_path/sqladvisor_path"- "./archery/soar_path/soar_path:/opt/archery/soar_path/soar_path"- "./archery/sql/migrations:/opt/archery/sql/migrations"- "./archery/logs:/opt/archery/logs"- "./archery/keys:/opt/archery/keys"entrypoint: "dockerize -wait tcp://192.168.0.213:3366 -wait tcp://redis:6379 -timeout 60s /opt/archery/src/docker/startup.sh"env_file:- .env==========================================================================
# 注意
entrypoint: "dockerize -wait tcp://192.168.0.213:3366 -wait tcp://redis:6379 -timeout 60s /opt/archery/src/docker/startup.sh" 这里的mysql地址一定要修改
修改.env文件
# pwd
/opt/Archery
# ls -a
. .. archery docker-compose.yml .env inception mysql# vim .env
NGINX_PORT=9123# https://django-environ.readthedocs.io/en/latest/quickstart.html#usage
# https://docs.djangoproject.com/zh-hans/4.1/ref/settings/
DEBUG=false#修改mysql配置信息
DATABASE_URL=mysql://archery:Archeryweb%123@192.168.0.213:3366/archery
CACHE_URL=redis://redis:6379/0?PASSWORD=123456# https://docs.djangoproject.com/en/4.0/ref/settings/#csrf-trusted-origins
CSRF_TRUSTED_ORIGINS=http://127.0.0.1:9123# https://django-auth-ldap.readthedocs.io/en/latest/
ENABLE_LDAP=false
AUTH_LDAP_ALWAYS_UPDATE_USER=true
AUTH_LDAP_USER_ATTR_MAP=username=cn,display=displayname,email=email# https://django-q.readthedocs.io/en/latest/configure.html#
Q_CLUISTER_WORKERS=4
Q_CLUISTER_TIMEOUT=60
Q_CLUISTER_SYNC=false
修改setting.py
# cd /opt/Archery/archery
# vim settings.py
# 修改SECRET_KEY
# 关闭debug模式
DEBUG = False
# 设置ALLOWED_HOSTS,建议限制内网访问
ALLOWED_HOSTS = ['.example.com', # Allow domain and subdomains'.example.com.', # Also allow FQDN and subdomains
]
# 请求大小限制,如果提交SQL语句过大可以修改该值
DATA_UPLOAD_MAX_MEMORY_SIZE = 15728640
# 密码校验,用户注册和添加密码校验规则
AUTH_PASSWORD_VALIDATORS = [{'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',},{'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator','OPTIONS': {'min_length': 9, }},{'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',},{'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',},
]#mysql配置
DATABASES = {'default': {'ENGINE': 'django.db.backends.mysql','NAME': 'archery', # 数据库名称'USER': 'archery', # 数据库用户'PASSWORD': 'Archeryweb%123', # 数据库密码'HOST': '192.168.0.213', # 数据库HOST,如果是docker启动并且关联,可以使用容器名连接'PORT': '3366', # 数据库端口'OPTIONS': {'init_command': "SET sql_mode='STRICT_TRANS_TABLES'", # SQL_MODE,为了兼容select * group by,可以按需调整'charset': 'utf8mb4'},'TEST': {'NAME': 'test_archery','CHARSET': 'utf8mb4',},}
}# Django-Q配置
Q_CLUSTER = {'name': 'archery','workers': 4,'recycle': 500,'timeout': 60,'compress': True,'cpu_affinity': 1,'save_limit': 0,'queue_limit': 50,'label': 'Django Q','django_redis': 'default','sync': False # 本地调试可以修改为True,使用同步模式}# 缓存配置
CACHES = {"default": {"BACKEND": "django_redis.cache.RedisCache","LOCATION": "redis://redis:6379/0", # redis://host:port/db"OPTIONS": {"CLIENT_CLASS": "django_redis.client.DefaultClient","PASSWORD": "123456"}}
}
docker-compose启动Archery
# pwd
/opt/Archery
# docker-compose create #根据docker-compose文件创建容器及网络或存储卷
# docker-compose up -d # 后台启动容器# 表结构初始化
docker exec -ti archery /bin/bash
cd /opt/archery
source /opt/venv4archery/bin/activate
python3 manage.py makemigrations sql
python3 manage.py migrate # 数据初始化
python3 manage.py dbshell<sql/fixtures/auth_group.sql
python3 manage.py dbshell<src/init_sql/mysql_slow_query_review.sql# 创建管理用户
python3 manage.py createsuperuser
#账户:admin 邮箱:admin@admin.com 密码:Fysladminexit# 重启
docker restart archery# 日志查看和问题排查
docker logs archery -f --tail=50
访问http://{ip}:9123
账户:admin 密码:Fysladmin
2.2、系统配置
GO_INCEPTION_HOST 192.168.0.213
GO_INCEPTION_PORT 4000
**BACKUP_HOST ** 192.168.0.213
BACKUP_PORT 3366
BACKUP_USER root
BACKUP_PASSWORD Archeryweb%123
SQLADVISOR_PATH /opt/archery/soar_path/sqladvisor_path
SOAR_PATH /opt/archery/soar_path/soar_path
三、测试
3.1、增加资源组
飞书机器人webhook地址:https://open.larksuite.com/open-apis/bot/v2/hook/xxxxxx
3.2、新建实例
注意:数据库账户权限需具有以下权限
- 1.对目标DB库需要有所有权限
- 2.对所有DB库具有REPLICATION SLAVE、REPLICATION CLIENT 、Select和Process权限,关于这个权限,官方文档并没有说明,此处需注意。
关于账户授权的sql语句示例如下:
create user 'archery'@'%' identified by 'Archeryweb%123' ;GRANT ALL on archery.* TO 'archery'@'%';GRANT REPLICATION SLAVE,REPLICATION CLIENT,Select,Process ON *.*
TO 'archery'@'%';flush privileges;
3.3、修改权限组
3.4、配置审批流程
3.5、修改新用户注册配置
测试新用户注册
账户:test001
密码:fysltest001
登录
可以看到之前配置的飞书机器人webhook已经发出通知了
登录DBA的账户,对申请进行批复
到这新用户注册的权限组测试完毕,新注册的用户仅能申请SQL查询权限
3.6、创建各类型测试用户
PM权限用户:
账户:PM-test001
密码:Fysltest03
DBA权限用户:
账户:DBA-test001
密码:Fysltest02
RD权限用户:
账户:RD-test004
密码:Fysltest03
3.7、创建上线sql/回滚
创建测试表
create table test(id int unsigned not null auto_increment primary key comment 'id',t2_name varchar(10) not null default 'a' comment 'a:有效,x:无效',cun varchar(10) not null default 'y' comment 'y:可用,n:不可用',email varchar(254) NOT NULL default ' ' comment '账户邮箱'
) comment 'table';
提交后根据审批流程,依次登录相关的测试账户审批
测试提交回滚SQL,这里省略(回滚步骤跟SQL上线步骤是一样的)
3.8、申请查询权限
略
3.9、申请归档权限
略
归档是将数据归档成sql文件或者csv文件,本步骤详情操作省略
3.10、数据脱敏
创建上线SQL,插入测试数据
INSERT INTOtest(id, t2_name, cun, email)
VALUES(1, 'a', 'y', 'zhangsan@gmail.com');
INSERT INTOtest(id, t2_name, cun, email)
VALUES(2, 'a', 'y', 'chensi@gmail.com');
INSERT INTOtest(id, t2_name, cun, email)
VALUES(3, 'a', 'y', 'wangwu@gmail.com');
配置数据脱敏字段
脱敏规则配置
测试数据脱敏效果
四、升级
升级分为两步, 数据库变更和服务更新, 以 Release v1.3.8 升级为 Release v1.5.0 为例
4.1、执行数据库变更脚本(请注意数据备份)
脚本文件地址: init_sql
需要执行当前版本至目标版本之间的所有数据库变更脚本
v1.3.8_v1.4.0.sql
v1.4.2_v1.4.3.sql
v1.4.3_v1.4.5.sql
v1.4.5_v1.5.0.sql
4.2、更新服务
1.使用 docker-compose -f docker-compose.yml down
停止旧版本服务, 删除旧版本服务使用的所有 docker 镜像
2.下载对应 Release 版本的压缩包: Releases
3.对比 src/docker-compose
文件夹, 按照最新配置进行调整, 注意务必更新 settings.py
文件, 否则可能无法启动, 确认配置没问题后使用 docker-compose -f docker-compose.yml up -d
启动新版本服务
4.执行数据库升级脚本, 跨多版本升级时需要执行当前版本至目标版本之间的所有数据库变更脚本(实际升级时注意替换文件名)
docker exec -it archery /bin/bash
source /opt/venv4archery/bin/activate
python manage.py dbshell < src/init_sql/v1.3.8_v1.4.0.sql
python manage.py dbshell < src/init_sql/v1.4.2_v1.4.3.sql
python manage.py dbshell < src/init_sql/v1.4.3_v1.4.5.sql
python manage.py dbshell < src/init_sql/v1.4.5_v1.5.0.sql
5.应用数据库变更 python manage.py migrate
6.使用 docker-compose -f docker-compose.yml restart
重新启动服务
五、踩坑记录
5.1.执行上线sql时报错 lookup mysql on 127.0.0.11:53: no such host
登录服务器查看容器 goinception日志
# docker logs -f goinception
################################################
Warning: The following parameters will be deprecated and replaced with disable_types:enable_blob_typeenable_json_typeenable_enum_set_bitenable_timestamp_type
https://github.com/hanchuanchuan/goInception/pull/418
################################################
time="2023/01/15 10:36:34.468" level=error msg="con:14 解析失败! line 5 column 2 near \") comment 'table'\" " file=session_inception.go func=executeInc line=220
time="2023/01/15 10:36:34.469" level=error msg=" create table test(\n id int unsigned not null auto_increment primary key comment 'id',\n t2_name varchar(10) not null default 'a' comment 'a:有效,x:无效',\n cun varchar(10) not null default 'y' comment 'y:可用,n:不可用',\n) comment 'table'" file=session_inception.go func=executeInc line=221
time="2023/01/15 10:38:53.933" level=error msg="con:17 con:17 dial tcp: lookup mysql on 127.0.0.11:53: no such host" file=session_inception.go func=parseOptions line=2134
可以看到goinception的备份数据库地址不正确,还是默认的127.0.0.1
解决方案:
修改goinception配置文件,将备份数据库信息修改
# pwd
/opt/Archery/inception# ls
config.toml# vim config.toml
...
##修改备份数据库信息
backup_host = "192.168.0.213"
backup_port = 3366
backup_user = "root"
backup_password = "Archeryweb%123"# cd ../
# pwd
/opt/Archery# docker-compose down# docker-compose up -d
再次提交SQL上线
可以看到执行正常结束
查看回滚SQL
执行上线SQL报错 lookup mysql on 127.0.0.11:53: no such host问题解决
5.2、执行上线SQL报错Execute: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation (sql: SHOW MASTER STATUS;).Execute: 无法获取master binlog信息.
登录服务器查看容器 goinception日志
# docker logs -f goinception
is operation" file=session_inception.go func=mysqlFetchMasterBinlogPosition line=1570
time="2020/09/03 15:50:48.804" level=error msg="con:8 Error 1227: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation" file=conn.go func=raw line=68
time="2020/09/03 15:50:48.804" level=error msg="con:8 Error 1227: Access denied; you need (at least one of) the SUPER, REPLICATION CLIENT privilege(s) for this operation" file=session_inception.go func=mysqlFetchMasterBinlogPosition line=1570
解决方案:
去连接每个实例的账户需要同时授予Replication Client、Replication Slave、Process和Select权限,缺一不可
GRANT REPLICATION SLAVE,REPLICATION CLIENT,Select,Process,Create,Update,Insert,Drop,DELETE ON *.*
TO 'archery'@'%';# 特别注意Drop,DELETE权限,生产不允许授这个权限,但是没有Drop,DELETE权限不能执行一些回滚sql,请联系管理员手动执行回滚sqlflush privileges;
关于这个权限,官方文档并没有说明,此处需注意。
相关文章:
Archery-SQL审核查询平台
Archery-SQL审核查询平台 文章目录Archery-SQL审核查询平台一、功能列表介绍1.1、SQL审核MySQL实例非MySQL实例审核执行分离SQL工单自动审批、高危语句驳回快速上线其他实例定时执行1.2、SQL查询多类型数据库支持授权管理页面体验1.3、SQL优化慢日志管理SQL语句优化1.4、实例管…...
MySQL8.0安装教程
文章目录1.官网下载MySQL2.下载完记住解压的地址(一会用到)3.进入刚刚解压的文件夹下,创建data和my.ini在根目录下创建一个txt文件,名字叫my,文件后缀为ini,之后复制下面这个代码放在my.ini文件下ÿ…...
一文详解工业知识模型互联平台MoHub
1月8日,MWORKS 2023产品发布会落下帷幕。会上,同元软控隆重推出了云原生的工业知识模型互联平台MoHub,引起广泛关注。本文将从服务定位、架构方案、核心服务、持续运营等方面对MoHub平台进行全面介绍。1 MoHub平台的服务定位装备数字化的必要…...
MySQL入门篇-MySQL表连接小结
备注:测试数据库版本为MySQL 8.0 这个blog我们来聊聊常见的表连接的方法 测试数据: create table t1(id int); create table t2(id int);insert into t1 values(1); insert into t1 values(2);insert into t2 values(2); insert into t2 values(3); commit;内连接 --求交集 …...
使用纹理(Textures)
当物体表面并非是纯色的时候,比如带波点,斑纹或者表面有刮痕或被裂纹等,这些效果该如何实现呢? 这里我们需要提到一个概念是贴图(Maps)。Maps是覆盖在游戏物体上的2D图片,用来设置表面的颜色、s…...
android 11 添加开机铃声
需求:在11.0在定制化系统中,默认是没有开机铃声的,有客户提出需要要添加开机铃声,所以为了完成需求,就来实现这一个功能关于开机铃声 都是在bootanimation_main.cpp 这里面负责管理。添加添加开机铃声的核心类framewor…...
操作系统考试突击复习笔记
0 基础概念补充特权命令:有特殊权限的指令,比如清内存、置时钟、分配系统资源、修改虚拟内存的段表和页表,修改用户的访问权限。系统调用:操作系统为应用程序提供的使用接口,可以理解为一种可供应用程序调用的特殊函数…...
java8函数式接口分布式事务简单实现方式
import java.util.List; import java.util.function.Function;/*** @ClassName TransactionFunctionDTO* @Description* @Author SD.LIU* @Date 2023/2/13 22:41* @Version 1.0**/ public class TransactionFunctionDTO...
最后一个单词的长度-力扣58-java
一、题目描述给你一个字符串 s,由若干单词组成,单词前后用一些空格字符隔开。返回字符串中 最后一个 单词的长度。单词 是指仅由字母组成、不包含任何空格字符的最大子字符串。示例 1:输入:s "Hello World"输出&#x…...
Java开发学习(四十九)----MyBatisPlus更新语句之乐观锁
1、概念 在讲解乐观锁之前,我们还是先来分析下问题: 业务并发现象带来的问题:秒杀 假如有100个商品或者票在出售,为了能保证每个商品或者票只能被一个人购买,如何保证不会出现超买或者重复卖 对于这一类问题,其实有很多的解决方…...
力扣SQL刷题11
目录标题1194. 锦标赛优胜者--做出来了1225. 报告系统状态的连续日期-勉强1159. 市场分析 II1205. 每月交易II1194. 锦标赛优胜者–做出来了 题型:看题 解答:先处理matches表,整出分数列和players表连接 注意点: union all 时…...
Fluent Python 笔记 第 9 章 符合 Python 风格的对象
得益于 Python 数据模型,自定义类型的行为可以像内置类型那样自然。实现如此自然的行为,靠的不是继承,而是鸭子类型(duck typing):我们只需按照预定行为实现对象所需的方法即可。 9.1 对象表示形式 实现 __repr__ 和 __str__ 特…...
档案管理数字化,成功的领导者,往往只问这3个问题
随着数字经济时代的到来,信息技术的更迭演进,逐渐改变了企业的办公业务流程,传统的办公业务模式已不能满足当前的企业业务需求。数字化转型成为当下企业的必选项。随着公司部门架构的日益复杂,流程繁多,产生海量的企业…...
自学软件测试从哪里开始?给还在迷茫的人一条出路
这两天和朋友谈到软件测试的发展,其实软件测试已经在不知不觉中发生了非常大的改变,前几年的软件测试行业还是一个风口,随着不断地转行人员以及毕业的大学生疯狂地涌入软件测试行业,目前软件测试行业“缺口”已经基本饱和。当然&a…...
配置MyBatis Plus 的分页查询功能
配置MyBatis Plus 的分页查询功能一. 回顾Mysql分页查询二. 配置MyBatis Plus 分页功能2.1 定义分页拦截器2.2 进行分页查询 selectPage()三. 开启MyBatis Plus的运行日志一. 回顾Mysql分页查询 limit 是MySQL当中特有的!其他数据库没有!不通用…...
Solon2 开发之插件,四、插件热插拔管理机制(H-Spi)
插件热插拔管理机制,简称:H-Spi。是框架提供的生产时用的另一种高级扩展方案。相对E-Spi,H-Spi 更侧重隔离、热插热拔、及管理性。 应用时,是以一个业务模块为单位进行开发,且封装为一个独立插件包。 1、特点说明 所…...
从react源码看hooks的原理
React暴露出来的部分Hooks //packages/react/src/React.js export {...useCallback,useContext,useEffect,useLayoutEffect,useMemo,useReducer,useRef,useState,... }功能描述 useState、useReducer: 状态值相关useEffect、useLayoutEffect: 生命周期相关useContext: 状态共…...
空间尺寸对迭代次数的影响
( A, B )---3*30*2---( 1, 0 )( 0, 1 ) ( A, B )---4*30*2---( 1, 0 )( 0, 1 ) 做4个训练集尺寸分别为3行3列,3行4列,4行3列和2行4列的网络。简写为3*3,3*4,4*3,2*4. 保持这4个网络差值结构的形态一致,…...
mininet+flowvisor+floodlight实现网络切片功能
ininetflowvisorfloodlight实现网络切片功能 这个项目所使用的软件flowvisor 和floodlight 都已经过时了网上能找到的资料太少了,整个项目搭建过程中遇到的坑太多了。花了大量的的时间。 有什么问题可提出来,如果我会的话一定会耐心解答的 此项目主要采…...
【C++】十分钟带你入门C++
目录零 内容概括一 C关键字二 命名空间2.1 命名空间定义2.2 命名空间的使用三 C输入和输出四 缺省参数4.1 缺省参数的概念4.2 缺省参数分类五 函数重载5.1 函数重载的概念六 引用6.1 引用概念6.2 引用特性6.3 常引用6.4 使用场景6.5 效率比较6.6 引用和指针的区别七 内联函数7.…...
kettle利用excel文件增量同步一个库的数据(多表一次增量同步)
利用excel文件增量同步一个库的数据 现在有sqlserver和mysql两个库上的表在进行同步,mysql上的是源表,sqlserver上是目标表。 mysql : sqlserver : 可以看到sqlserver上表的最近一次同步日期分别是 pep表: 2022-10-23 14:19:00.000 stu_…...
面试题:android中A Activity 打开B Activity,为什么A Activity的onStop()方法最后被调用
如下是一段典型的Activity间切换的日志,从A Activity切换到B Activity:10-17 20:54:42.247: I/com.example.servicetest.AActivity(5817): onCreate() 1166919192 taskID66 10-17 20:54:42.263: I/com.example.servicetest.AActivity(5817): onStart()…...
百度版本gactgpt即将来临,gpt人工智能机器横空出世
百度版本gactgpt即将来临,gpt人工智能机器横空出世,“一言”为定!百度版ChatGPT确认!李彦宏OKR曝光,率先应用于收索业务 gactCBT 大获,当下极有可能成为人工智能的 iPhone 时刻。为了在这场人工智能竞赛中…...
【python--networkx】函数说明+代码讲解
【Python–NetworkX】函数说明代码讲解 文章目录【Python--NetworkX】函数说明代码讲解1. 介绍1.1 前言1.2 图的类型(Graph Types)1.3 常用方法2. 代码示例1. 介绍 1.1 前言 NetworkX是复杂网络研究领域中的常用Python包。 1.2 图的类型(G…...
【Jqgrid分页勾选保存】三步实现表格分页勾选(取消勾选)保存(附源码)
目录1、创建临时存储数组,初始化赋值2、单行选中与取消,调整数组3、全选与取消全选,调整数组4、输出数组保存5、片尾彩蛋【写在前面】表格可以说是在我们的web页面中是最常见的,之前我们介绍过layui表格翻页勾选的实现过程&#x…...
Appium移动自动化测试——app控件获取之uiautomatorviewer
下载手机YY http://yydl.duowan.com/mobile/yymobile_client-android/5.4.2/yymobile_client-5.4.2-881.apk 若链接失效,请自行百度 新建maven空白工程 前置条件:安装eclipse,及其maven插件,请自行百度 新建的工程如下…...
webpack、vite、vue-cli、create-vue 的区别
webpack、vite、vue-cli、create-vue 的区别 首先说结论 Rollup更适合打包库,webpack更适合打包项目应用,vite基于rollup实现了热更新也适合打包项目。 功能工具工具脚手架vue-clicreate-vue构建项目vite打包代码webpackrollup 脚手架:用于初始化&#…...
数据结构——TreeMap、TreeSet与HashMap、HashSet
目录 一、Map 1、定义 2、常用方法 3、注意 二、TreeMap 三、HashMap 1、定义 2、冲突定义 3、冲突避免方法——哈希函数设计 (1)、直接定制法(常用) (2)、除留余数法(常用) (3)、平方取中法 &…...
Spring Boot学习篇(十三)
Spring Boot学习篇(十三) shiro安全框架使用篇(五) 1 准备工作 1.1 在SysUserMapper.xml中书写自定义标签 <select id"findRoles" resultType"string">select name from sys_role where id (select roleid from sys_user_role where userid (S…...
微软Bing的AI人工只能对话体验名额申请教程
微软Bing 免费体验名额申请教程流程ChatGPT这东西可太过火了。国外国内,圈里圈外都是人声鼎沸。微软,谷歌,百度这些大佬纷纷出手。连看个同花顺都有GPT概念了,搞技术,做生意的看来都盯上了 流程 下面就讲一下如何申…...
网站数据库出问题/长春网站关键词排名
2019独角兽企业重金招聘Python工程师标准>>> wchar_t引发的思考 - wen_dao_ - 博客园http://www.cnblogs.com/wendao/archive/2012/07/27/2612597.html 字符集和字符编码(Charset & Encoding) - 吴秦 - 博客园 http://www.cnblogs.com/sk…...
博客wordpress主题/软件开发需要多少资金
方案介绍亚马逊云科技 WAF 是一个网页应用的防火墙服务。它能帮助保护您的网页应用或网页 API 应对常见的网页攻击。在 WAF 部署小指南(一) 中,我们讨论了 WAF 的原理,如何使用 WAF,以及如何将 WAF 日志存储在 Amazon S3 中,并通过…...
2015年做那些网站致富/google app
相比传统的版本管理工具,git 的 undo 操作也不是很简单明了,本文尝试总结常用的 undo 操作。 重新提交 应该避免考虑不周全的提交,但这太难了。因此Git 专门提供了一个命令来弥补粗心的提交导致的问题。说白了就是让你重新提交一次。 $ git c…...
凡科网做网站的图片/住房和城乡建设部官网
学习总结: 通过这一周的学习,我学到了很多新知识。通过看视频,我又进一步学习了java,对java有了更深的了解,也通过在网上找有关HTML和CSS的介绍,我现在已经大概了解了这些东西。在刚开始真的以为这些东西好…...
电子商务网站建设实训方案/抖音seo优化公司
在JS中。是没有块级作用域的 举两个个样例: if语句块: if (true){var nameLing; } alert(name);输出:Ling for语句块; for(var i0;i<10;i) {var nameLing; } alert(i); alert(name);输出:10 输出:Ling 也就是说…...
微信网站后台/宁波核心关键词seo收费
APP扫码登录流程(借鉴微信扫码登录流程,注意区分:WEB客户端和WEB服务端;APP客户端和APP服务端;) 1、【WEB端】WEB端请求登录二维码:用户打开WEB系统网页,用户触发浏览器向WEB服…...