• [技术干货] 鲲鹏ARM架构下OpenGauss未来展望
    随着国产化替代浪潮的推进,鲲鹏处理器作为自主研发的高性能架构,与开源数据库 OpenGauss 的组合已成为企业级应用的核心选择。OpenGauss 作为华为主导的分布式关系型数据库,天然适配鲲鹏架构的 ARM 指令集,在性能优化、安全特性、高可用设计上深度协同。本文将从架构适配原理出发,详细讲解 OpenGauss 在鲲鹏环境下的部署流程、性能调优技巧及生产环境实践经验,助力企业快速落地国产化数据库方案。一、架构适配:为什么 OpenGauss + 鲲鹏是黄金组合?1.1 指令集深度协同鲲鹏处理器基于 ARM v8 架构,采用精简指令集(RISC)设计,具备低功耗、高并发、多核优势;而 OpenGauss 从内核层面针对 ARM 架构进行了指令优化,包括:汇编级指令替换:将热点函数(如数据加密、哈希计算)用 ARM Neon 指令重写,提升计算效率;内存访问优化:适配鲲鹏的三级缓存架构,优化数据预取策略,减少缓存命中率低的问题;多核调度适配:针对鲲鹏处理器的多 NUMA 节点设计,优化线程亲和性,避免跨节点调度开销。1.2 国产化生态闭环OpenGauss 作为开源国产数据库,与鲲鹏架构、欧拉(openEuler)操作系统共同构成 "芯片 - 操作系统 - 数据库" 的国产化生态闭环。该组合通过了严格的兼容性测试,在政务、金融、能源等关键领域已大规模落地,具备完善的技术支持和生态保障。1.3 核心优势互补特性鲲鹏架构贡献OpenGauss 数据库贡献性能多核高并发、硬件加速(如 AES)分布式架构、查询优化器、列存引擎安全硬件级可信执行环境(TEE)透明加密、访问控制、审计日志高可用双路 / 四路服务器冗余设计主备复制、故障自动切换、数据备份扩展性支持 CPU 扩展至 128 核以上水平分库分表、分布式事务  二、部署前准备:环境规划与依赖检查2.1 硬件环境要求(生产级配置)组件最低配置推荐配置CPU鲲鹏 920 2.6GHz(8 核 16 线程)鲲鹏 920 2.6GHz(32 核 64 线程)内存32GB(主备模式)128GB(分布式模式)存储SSD 500GB(系统盘)+ HDD 2TB(数据盘)NVMe SSD 1TB(系统盘)+ SAS 10TB(数据盘,RAID 5)网络千兆以太网25Gbps InfiniBand(分布式集群)操作系统openEuler 22.03 LTS(ARM64)openEuler 22.03 LTS(ARM64)  2.2 软件依赖安装OpenGauss 依赖以下组件,需提前在鲲鹏服务器上安装:  # 1. 安装基础依赖包yum install -y gcc gcc-c++ make cmake zlib-devel libffi-devel openssl-devel libuuid-devel# 2. 安装Python 3.8+(OpenGauss管理工具依赖)yum install -y python3 python3-devel python3-pip# 3. 安装libatomic(ARM架构必需,原子操作支持)yum install -y libatomic# 4. 关闭防火墙和SELinux(生产环境可配置白名单)systemctl stop firewalld && systemctl disable firewalldsed -i 's/SELINUX=enforcing/SELINUX=disabled/' /etc/selinux/configsetenforce 0   2.3 系统参数优化(关键步骤)为适配 OpenGauss 的运行需求,需调整鲲鹏服务器的系统参数,编辑/etc/sysctl.conf:  # 编辑系统参数配置文件vim /etc/sysctl.conf# 添加以下配置(针对鲲鹏ARM架构优化)net.ipv4.tcp_max_tw_buckets = 10000net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1net.ipv4.tcp_syncookies = 1net.core.somaxconn = 65535net.core.netdev_max_backlog = 65535net.ipv4.tcp_max_syn_backlog = 65535vm.swappiness = 10 # 减少内存交换,提升性能vm.dirty_ratio = 30vm.dirty_background_ratio = 10kernel.shmmax = 68719476736 # 共享内存最大值(建议为物理内存的50%)kernel.shmall = 16777216# 生效配置sysctl -p 同时调整文件描述符限制,编辑/etc/security/limits.conf:  # 添加以下配置* soft nofile 65535* hard nofile 65535* soft nproc 131072* hard nproc 131072 三、OpenGauss 部署:主备模式实战(鲲鹏环境)OpenGauss 支持单机、主备、分布式三种部署模式,本文以生产常用的主备模式为例,讲解在两台鲲鹏服务器上的部署流程(主节点:192.168.1.10,备节点:192.168.1.11)。3.1 下载 OpenGauss 安装包从 OpenGauss 官网下载适配 ARM 架构的安装包(选择 openEuler ARM64 版本):  # 创建安装目录mkdir -p /opt/opengauss && cd /opt/opengauss# 下载安装包(示例版本:3.1.0,需替换为最新版本)wget https://opengauss.obs.cn-south-1.myhuaweicloud.com/3.1.0/x86_openEuler_64bit/opengauss-3.1.0-openEuler-64bit.tar.bz2# 解压安装包tar -jxvf opengauss-3.1.0-openEuler-64bit.tar.bz2   3.2 配置免密登录(主备节点互信)主备节点需实现 SSH 免密登录,确保安装脚本可跨节点执行:  # 在主节点生成密钥对(无需设置密码)ssh-keygen -t rsa -P "" -f ~/.ssh/id_rsa# 将公钥拷贝到备节点ssh-copy-id -i ~/.ssh/id_rsa.pub root@192.168.1.11# 验证免密登录(无需输入密码即可登录)ssh root@192.168.1.11 3.3 编写部署配置文件创建cluster_config.xml配置文件,定义主备节点信息:  <?xml version="1.0" encoding="UTF-8"?><ROOT> <!-- 全局配置 --> <CLUSTER> <PARAM name="clusterName" value="opengauss_cluster"/> <PARAM name="nodeNames" value="node1,node2"/> <PARAM name="gaussdbAppPath" value="/opt/opengauss/app"/> <PARAM name="gaussdbDataPath" value="/opt/opengauss/data"/> <PARAM name="gaussdbLogPath" value="/opt/opengauss/log"/> <PARAM name="dataBasePort" value="5432"/> <PARAM name="masterNode" value="node1"/> </CLUSTER> <!-- 主节点配置 --> <NODE name="node1" hostname="192.168.1.10" ip="192.168.1.10" azName="AZ1" azPriority="1"/> <!-- 备节点配置 --> <NODE name="node2" hostname="192.168.1.11" ip="192.168.1.11" azName="AZ1" azPriority="2"/></ROOT>   3.4 执行安装脚本  # 进入安装目录cd /opt/opengauss/opengauss-3.1.0-openEuler-64bit# 执行安装脚本(--help可查看参数说明)./install.sh -m primary -c ../cluster_config.xml -w 'OpenGauss@123'# 安装成功后,验证集群状态gs_om -t status --detail 3.5 安装验证  # 登录OpenGauss数据库gsql -d postgres -U gaussdb -h 192.168.1.10 -p 5432# 执行SQL查询,验证数据库状态SELECT version();SELECT node_name, node_role, node_state FROM pg_stat_replication; 若查询结果显示主备节点状态为Primary和Standby,且 replication 状态正常,则部署成功。四、性能调优:鲲鹏架构专属优化技巧4.1 数据库参数优化(postgresql.conf)针对鲲鹏处理器的多核、大内存特性,调整以下关键参数:  # 编辑配置文件(主备节点需同步修改)vim /opt/opengauss/data/postgresql.conf# 核心优化参数max_connections = 8192 # 最大连接数(鲲鹏多核可支持更高并发)shared_buffers = 32GB # 共享内存(建议为物理内存的25%)work_mem = 64MB # 每个工作线程的内存(根据并发调整)maintenance_work_mem = 2GB # 维护操作内存(如索引创建)effective_cache_size = 96GB # 有效缓存大小(建议为物理内存的75%)wal_buffers = 16MB # WAL日志缓冲区checkpoint_completion_target = 0.9 # checkpoint完成目标(减少IO峰值)max_parallel_workers_per_gather = 8 # 每个查询的并行工作线程数(建议为CPU核心数的1/4)parallel_leader_participation = on # 领导者参与并行查询# 生效配置(无需重启数据库)gs_ctl reload -D /opt/opengauss/data 4.2 存储优化(针对鲲鹏服务器存储架构)使用 NVMe SSD 作为数据盘:鲲鹏服务器支持 PCIe 4.0 接口,NVMe SSD 可发挥最大 IO 性能,建议将数据目录和 WAL 目录分别挂载到不同的 NVMe SSD;关闭磁盘缓存刷新:在 RAID 卡配置中启用 "写缓存策略"(Write Back),提升写性能;文件系统选择:推荐使用 XFS 文件系统,格式化时指定-s size=4096(与鲲鹏处理器的内存页大小对齐)。4.3 网络优化(分布式集群场景)启用 RSS 中断均衡:鲲鹏服务器支持 RSS(接收端缩放),可将网络中断分散到多个 CPU 核心:  # 启用RSSethtool -C eth0 rx-usecs 100ethtool -K eth0 rxvlan on 调整 TCP 参数:优化网络连接稳定性和吞吐量(已在部署前配置);使用 InfiniBand 网络:分布式集群建议采用 25Gbps 以上的 InfiniBand 网络,降低节点间通信延迟。4.4 性能测试验证使用gs_perf工具测试优化后的性能(对比优化前后的 TPCC、TPC-H 指标):  # 执行TPCC测试(1000仓库规模)gs_perf -M tpcc -D testdb -U gaussdb -w 'OpenGauss@123' -s 1000 -c 64# 执行TPC-H测试(100GB数据量)gs_perf -M tpch -D testdb -U gaussdb -w 'OpenGauss@123' -s 100 -c 32 在鲲鹏 920 32 核服务器上,优化后 OpenGauss 的 TPCC 吞吐量可提升 30% 以上,TPC-H 查询延迟降低 20% 左右。五、生产环境实践:高可用与运维最佳实践5.1 主备切换实战OpenGauss 支持自动故障切换,也可手动触发切换:  # 手动切换主备节点(在备节点执行)gs_ctl switchover -D /opt/opengauss/data# 切换后验证状态gs_om -t status --detail 5.2 数据备份与恢复  # 全量备份gs_basebackup -D /opt/opengauss/backup -h 192.168.1.10 -p 5432 -U gaussdb -F p -X stream -P -v# 恢复数据(需停止数据库)gs_ctl stop -D /opt/opengauss/datarm -rf /opt/opengauss/data/*gs_basebackup -D /opt/opengauss/data -h 192.168.1.10 -p 5432 -U gaussdb -F p -X stream -P -v -Cgs_ctl start -D /opt/opengauss/data   5.3 监控告警配置启用内置监控工具:OpenGauss 提供gs_monitor工具,可监控数据库状态、性能指标:  gs_monitor -d postgres -U gaussdb -h 192.168.1.10 -p 5432 -w 'OpenGauss@123' -t 30 集成 Prometheus+Grafana:通过 OpenGauss 的导出器(exporter)将指标接入监控系统,配置 CPU、内存、IO、连接数等告警阈值。5.4 安全加固修改默认密码:生产环境需定期更换数据库管理员密码,复杂度需满足大小写字母 + 数字 + 特殊字符;配置访问控制:通过pg_hba.conf限制允许访问的 IP 地址:  vim /opt/opengauss/data/pg_hba.conf# 添加白名单配置host all all 192.168.1.0/24 md5 启用透明加密:OpenGauss 支持数据文件透明加密,需在部署时指定加密密钥。六、常见问题与排查方案6.1 安装失败:libatomic.so.1 缺失问题原因:鲲鹏 ARM 架构缺少原子操作库。解决方案:  yum install -y libatomicln -s /usr/lib64/libatomic.so.1 /usr/lib/libatomic.so.1 6.2 主备同步失败: replication 连接超时问题原因:防火墙未开放 5432 端口,或网络延迟过高。解决方案:  # 开放端口(生产环境建议配置白名单)firewall-cmd --add-port=5432/tcp --permanentfirewall-cmd --reload# 检查网络延迟ping 192.168.1.11 -c 10traceroute 192.168.1.11 6.3 性能瓶颈:CPU 使用率过高问题原因:SQL 语句未优化,或并行查询参数配置不合理。解决方案:用gs_top查看占用 CPU 较高的会话和 SQL;优化 SQL 语句(添加索引、调整 join 方式);降低max_parallel_workers_per_gather参数,避免并行查询占用过多 CPU。七、展望OpenGauss 在鲲鹏架构下的部署与优化,核心在于架构协同和参数适配。通过本文的部署流程、优化技巧和实践经验,企业可快速搭建稳定、高性能的国产化数据库环境。随着 OpenGauss 4.0 版本的发布,其在分布式事务、HTAP 混合负载、AI 优化等方面的能力将进一步增强,与鲲鹏架构的协同效应也将更加显著。在国产化替代的大趋势下,掌握 OpenGauss + 鲲鹏的组合技术,不仅能提升企业 IT 架构的自主可控性,还能获得性能与成本的双重优势。建议运维和 DBA 人员深入理解两者的架构特性,结合业务场景进行针对性优化,充分发挥国产化软硬件的潜力。
  • openGauss 全密态数据库:计算过程隐私保护技术解析
    openGauss 全密态数据库通过 "全链路密文处理 + 硬件安全执行环境" 的核心技术组合,实现了数据在计算过程中的隐私保护,确保即使数据库服务端也无法获取用户敏感数据的明文信息一、全密态核心架构与工作流程全密态数据库的隐私保护基于 "数据全生命周期密态化"理念,实现"原始数据不出域、数据可用不可见"阶段核心操作隐私保护机制数据写入客户端加密→密文存储用户持有密钥,服务端仅存密文计算处理密文查询 / 运算→密文结果服务端不解密直接处理密文或在安全环境内解密计算结果返回服务端返回密文→客户端解密结果始终以密态传输,仅用户可见明文二、数据计算隐私保护的四大技术支柱1. 双密钥管控体系客户端主密钥 (CMK):用户生成并完全掌控,存储于客户端安全区域,不泄露给服务端数据加密密钥 (CEK):由 CMK 派生,用于数据加密,以密文形式存储在数据库系统表中密钥管理流程: 用户→CREATE CLIENT MASTER KEY→CMK(客户端生成)→CREATE COLUMN ENCRYPTION KEY→CEK(CMK加密)→存储于系统表 2. 密文计算引擎:原生支持密文处理全密态数据库对 openGauss 内核进行了深度改造,实现了 "查询解析→执行计划→数据访问→结果返回" 全链路密文处理能力查询重写:自动将明文查询条件转换为密文查询条件,防止查询意图泄露表达式计算:支持密文状态下的比较、算术、逻辑等操作,性能损失控制在 5-10%索引优化:专为密文设计的索引结构,支持高效密态查询,无需解密数据3. TEE 硬件安全执行环境 (软硬融合方案)对于复杂计算,全密态数据库采用 **"硬件机密计算 + 软件加密"** 融合方案,通过可信执行环境 (TEE) 构建安全计算孤岛:Enclave 安全容器:在服务器 CPU 硬件中创建隔离执行空间,保证内部计算和数据机密性密文安全解密:仅在 Enclave 内解密必要数据片段,计算完成后立即销毁明文,全程不暴露给服务端系统远程证明:客户端可验证计算确实在可信硬件环境中执行,防止中间人攻击4. 端到端密态传输与处理客户端→数据库→客户端全链路密态流转,确保数据在任何环节均不以明文形式出现: 客户端应用→(驱动加密)→密文SQL→数据库→(密文计算)→密文结果→(驱动解密)→客户端应用 三、计算过程隐私保护的具体实现机制1. 等值查询密态处理这是全密态数据库的基础能力,支持在不解密情况下判断两个密文值是否相等加密算法选择:支持 AES、SM4 等多种国密 / 国际算法,确保密文具有确定性 (相同明文生成相同密文)查询条件转换:用户输入的明文查询条件在客户端自动加密,以密文形式传递给数据库结果过滤:数据库直接对密文数据进行匹配,返回满足条件的密文记录,仅客户端可见明文结果2. 复杂计算的隐私保护实现对于聚合、连接等复杂操作,全密态数据库采用两种处理模式:模式一:纯密态计算(适用于简单聚合)数据库直接对密文数据执行 SUM、COUNT 等聚合运算,返回密态聚合结果客户端解密后获得最终聚合值,服务端无法获知具体数值模式二:硬件安全计算(适用于复杂分析)数据库将密文数据传输至 TEE 安全环境在 Enclave 内部解密、计算,仅返回密态计算结果整个过程服务端操作系统无法访问明文,保证 "数据可用不可见"3. 特殊场景的隐私增强机制动态数据脱敏:查询结果返回前,可根据用户权限对部分敏感字段进行脱敏处理,实现 "按需可见"密文连接优化:支持基于密文键值的 JOIN 操作,无需解密关联字段采用特殊哈希算法,保证密文键值在连接操作中的高效匹配四、全密态数据库隐私保护的关键优势优势具体表现隐私保护价值零信任架构服务端与客户端互相不信任,数据全程密态即使数据库管理员也无法获取用户数据明文全链路保护存储、传输、计算、审计全环节密态防止任何单点突破导致的隐私泄露最小暴露原则按需解密,仅在必要时、必要范围内短暂解密减少明文数据暴露窗口和范围合规支持满足 GDPR、等保 2.0、行业隐私规范要求降低企业合规成本和法律风险性能保障优化的密文算法和执行路径,性能损失 < 10%在强隐私保护下保持业务处理效率五、总结一下下:全密态数据库隐私保护的核心逻辑openGauss 全密态数据库通过 "数据全生命周期密态化 + 硬件安全执行环境 + 智能查询处理"三位一体的技术架构,在计算过程中实现了全方位隐私保护。其核心逻辑是:用户掌握密钥→数据全程密态→计算在安全环境中进行→结果仅用户可见,从技术上彻底解决了传统数据库面临的数据泄露风险,特别适合金融、医疗、政务等对隐私要求极高的场景。全密态数据库代表了数据库安全的发展方向,实现了 "让数据可用但不可见" 的隐私保护终极目标,为企业数字化转型提供了坚实的安全保障。
  • openGauss之用户和角色
    openGauss概述openGauss是关系型数据库,采用客户端/服务器,单进程多线程架构;支持单机和一主多备部署方式,同时支持备机可读、双机高可用等特性。openGauss有如下基本功能:1、支持标准SQLopenGauss数据库支持标准的SQL(Structured Query Language,结构化查询语言)。SQL标准是一个国际性的标准,定期会进行更新和演进。SQL标准的定义分成核心特性以及可选特性,绝大部分的数据库都没有100%支撑SQL标准。openGauss数据库支持SQL92/SQL99/SQL2003等,同时支持SQL2011大部分的核心特性,另外还支持部分的可选特性。2、支持标准开发接口openGauss数据库提供业界标准的ODBC(Open Database Connectivity,开放式数据库连接)及JDBC(Java Database Connectivity,java数据库连接)接口,保证用户能将业务快速迁移至openGauss。目前支持标准的ODBC3.5及JDBC4.0接口,其中ODBC能够支持CentOS、openEuler、SUSE、Win32、Win64等平台,JDBC无平台差异。3、混合存储引擎支持openGauss数据库支持行存储引擎、列存储引擎和内存存储引擎等。行存分为“inplace update” 和 “append update”两种模式,前者通过单独的回滚段(undo log)来保留元组的前像以解决读写冲突,可以更自然的支持数据更新;后者将更新记录混杂在数据记录中,通过新旧版本的形式来支持数据更新,对于旧版本需要定期做vacuum操作来支持磁盘空间的回收。列存支持数据快速分析,更适合OLAP(Online Analytical Processing,联机分析处理)业务。内存引擎支持实时数据处理,对有极致性能要求的业务提供支撑。4、事务支持事务支持指的就是系统提供事务的能力,openGauss支持事务的原子性、一致性、隔离性和持久性。事务支持及数据一致性保证是绝大多数数据库的基本功能,只有支持了事务,才能满足事务化的应用需求。用户和角色管理是数据库管理系统中的重要功能,用于管理数据库中的用户和角色,以控制对数据库的访问权限。用户是数据库中的实体,用于标识和管理数据库中的各种操作权限和资源使用权限。而角色是一组权限的集合,可以将一组用户分配到同一个角色上,从而简化权限管理和控制。在openGauss数据库中,用户和角色管理可以通过SQL语句或者openGauss控制台来完成。通过创建、修改、删除用户和角色,可以控制用户的身份验证和访问权限。用户 使用数据库系统服务的个体  职责单一,往往附属于某个组织或部门用户可以做什么  使用工具连接数据库  访问数据库对象  执行SQL语句角色 角色是一组用户的集合,按照数据库系统中承担的责任划分具有不同权限的角色;角色用来作 为权限集合的载体。 ⚫ openGauss 提供了一个隐式定义的拥有所有角色的组PUBLIC,所有创建的用户和角色默 认拥有PUBLIC所拥有的权限。 ⚫ 要撤销或重新授予用户和角色对PUBLIC的权限,可通过在GRANT和REVOKE指定关键字 PUBLIC实现。用户与角色⚫ 用户是实体,角色是行为。 ⚫ 用户可被赋予一个或多个角色。⚫ 角色是一种权限集合,不应该具有登录数据库并执行SQL的能力。 ⚫ 对用户权限的管理,可以简化为对角色权限的管理。 ⚫ 在openGauss中,用户和角色使用相同的操作方式与维护方式。实际使用中的选择在OpenGauss中,CREATE USER更常用于以下场景:需要创建实际登录数据库的账号时为应用程序或个人用户创建账户时而CREATE ROLE通常用于:创建权限组(如read_only_role, write_role等)实现权限继承和组合作为模板角色语法CREATE USER name [ [ WITH ] option [ ... ] ] 这里 option 可以是: SUPERUSER | NOSUPERUSER | CREATEDB | NOCREATEDB | CREATEROLE | NOCREATEROLE | INHERIT | NOINHERIT | LOGIN | NOLOGIN | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] | USER role_name [, ...] | SYSID uid修改角色/用户ALTER USER role_specification [ WITH ] option [ ... ] 其中 option 可以是: SUPERUSER | NOSUPERUSER | CREATEDB | NOCREATEDB | CREATEROLE | NOCREATEROLE | INHERIT | NOINHERIT | LOGIN | NOLOGIN | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' ALTER USER name RENAME TO new_name ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT } ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL删除角色/用户DROP USER [ IF EXISTS ] name [, ...]查询类操作:  openGauss的用户、角色属性维护在pg_authid系统表中,pg_user、pg_roles视图也可以查询 用户、角色信息。  使用\d命令查看pg_authid表详细信息。  使用select命令查询pg_authid中的相关信息。角色属性角色可以拥有属性,属性确定了角色拥有的特权,并且在登录时与客户端认证系统进行交互。常见的角色属性包括:• 登录特权,只有具有 LOGIN 属性的角色才能连接数据库。具有 LOGIN 角色的用户可以被看作一个“数据库用户”。使用以下语句创建具有登录特权的角色:CREATE ROLE name LOGIN;CREATE USER name;CREATE USER 与 CREATE ROLE 都可以用于创建角色,只不过 CREATE USER 默认包含了 LOGIN 选项,而 CREATE ROLE 没有。• 超级用户,数据的超级用户可以避开所有的权限检查,只验证登录权限。因此,这是一个很危险的特权,使用时需要特别小心;最好在日常的操作中避免使用超级用户。使用以下命令创建一个新的超级用户:CREATE ROLE name SUPERUSER;只有超级用户才能创建其他的超级用户。• 创建数据库,只有明确授权的角色才能够创建数据库(超级用户除外,因为他们可以避开权限检查)。使用以下语句创建一个具有数据库创建特权的角色:CREATE ROLE name CREATEDB;• 创建角色,只有明确授权的角色才能够创建其他角色(超级用户除外,因为他们可以避开权限检查)。使用以下命令创建一个具有角色创建特权的角色:CREATE ROLE name CREATEROLE;具有 CREATEROLE 特权的角色还可以修改或删除其他角色,以及为这些角色授予或者撤销成员角色。但是,针对超级用户的创建、修改、删除,以及它的成员变更,需要超级用户特权;CREATEROLE 特权无法针对超级用户执行这些操作。• 启动复制,只有明确授权的角色才能够启动流复制(超级用户除外,因为他们可以避开权限检查)。用于流复制的角色还需要拥有 LOGIN 特权。使用以下语句创建可以用于流复制的角色:CREATE ROLE name REPLICATION LOGIN;• 密码,只有当用户连接数据库使用的客户端认证方法要求提供密码时,密码属性才有意义。password 和 md5 认证方法需要使用密码。数据库的密码与操作系统的密码相互独立。使用以下语句在创建角色时指定密码:CREATE ROLE name PASSWORD 'string';我们在创建角色时,可以根据需要指定某些属性。例如,以下命令创建一个具有登录特权的角色 tony,并且为它指定了密码以及密码过期时间:CREATE ROLE tony WITH LOGIN PASSWORD 'Pass2019' VALID UNTIL '2020-01-01';-- CREATE USER tony WITH PASSWORD 'Pass2019' VALID UNTIL '2020-01-01';使用该用户连接到 postgres 数据库:[root@centos7 ~]# psql -h 192.168.56.103 -p 5432 -U tony postgresPassword for user tony:psql (14.2)Type "help" for help.postgres=> \cYou are now connected to database "postgres" AS user "tony".psql 命令行工具支持许多选项,-h 表示数据库服务器的地址,-p 表示服务的监听端口,-U表示登录使用的用户名,最后的 postgres 代表要连接的数据库。详细的命令行参数可以使用 psql--help 查看。以下命令创建一个管理角色 admin,它具有创建数据库和创建角色的特权:opengauss=# CREATE ROLE admin CREATEDB CREATEROLE; CREATE ROLE在实践中,最好创建一个拥有 CREATEDB 和 CREATEROLE 特权,但不具有超级用户特权的管理角色,然后使用该角色执行日常的数据库和角色的管理。这种方式可以避免过度使用超级用户可能带来的风险。一个角色被创建之后,可以通过 ALTER ROLE 语句修改它的属性。例如,以下命令可以撤销角色 admin 创建角色的特权:opengauss=# ALTER ROLE admin NOCREATEROLE; ALTER ROLE2.3 对象授权当我们使用新创建的用户(tony)连接数据库(hrdb)之后,执行以下查询语句:hrdb=> SELECT * FROM employees; ERROR: permission denied for table employees以上语句执行错误是因为用户没有相应对象上的访问权限。opengauss使 GRANT 语句进行数据库对象的授权操作。以表为例,基本的授权语法如下:GRANT privilege_list | ALL ON [ TABLE ] table_name TO role_name;其中,privilege_list 权限列表可以是 SELECT、INSERT、UPDATE、DELETE、TRUNCATE等,ALL 表示表上的所有权限。例如,使用 gauss用户连接 hrdb 数据库后执行以下语句:hrdb=# GRANT SELECT, INSERT, UPDATE, DELETE hrdb-# ON employees, departments, jobs hrdb-# TO tony;GRANT该语句将 employees、departments 和 jobs 表上的增删改查权限授予了 tony 用户。此时 tony用户就可以访问这些表中的数据:hrdb=> SELECT first_name, last_name FROM employees;对表进行授权的 GRANT 语句还支持一些其他选项:GRANT privilege_list | ALL ON ALL TABLES IN SCHEMA schema_name TO role_name;ALL TABLES IN SCHEMA 表示某个模式中的所有表,可以方便批量授权操作。例如:hrdb=# GRANT SELECT hrdb-# ON ALL TABLES IN SCHEMA public hrdb-# TO tony;GRANT该语句将 public 模式中所有表的查询权限授予 tony 用户。我们也可以在 GRANT 语句的最后指定一个 WITH GRANT OPTION,意味着被授权的角色可以将该权限授权其他角色。例如:hrdb=# GRANT SELECT, INSERT, UPDATE, DELETE hrdb-# ON employees, departments, jobs hrdb-# TO tony WITH GRANT OPTION;此时,tony 用户不但拥有这些表上的访问权限,还可以将这些权限授予其他角色。除了授权表的访问权限之外,GRANT 语句还支持字段、视图、序列、数据库、函数、过程、模式等对象的授权操作。2.4 撤销授权与授权操作相反的就是撤销权限,opengauss使 REVOKE 语句撤销数据库对象上的权限。同样以表为例,基本的撤销授权语句如下:REVOKE privilege_list | ALL ON TABLE table_name FROM role_name;其中的参数和 GRANT 语句一致。例如:hrdb=# REVOKE SELECT, INSERT, UPDATE, DELETE hrdb-# ON employees, departments, jobs hrdb-# FROM tony;REVOKE该语句撤销了用户 tony 访问 employees、departments 以及 jobs 表的权限。REVOKE 语句也支持对某个模式中的所有对象进行操作:REVOKE privilege_list | ALL ON ALL TABLES IN SCHEMA schema_name FROM role_name;例如以下语句撤销了用户 tony 在 public 模式中所有表上的查询权限:hrdb=# REVOKE SELECT hrdb-# ON ALL TABLES IN SCHEMA public hrdb-# FROM tony;REVOKE与 GRANT 语句对应,REVOKE 语句还支持字段、视图、序列、数据库、函数、过程、模式等对象的撤销授权操作。2.5 角色成员在现实的环境中,管理员通常需要管理大量的用户和对象权限。为了便于权限管理,减少复杂度,可以将用户进行分组,然后以组为单位进行权限的授予和撤销操作。为此,opengauss引入了组(group)角色的概念。具体来说,就是创建一个代表组的角色,然后将该组的成员资格授予其他用户,让其成为该组的成员。首先,使用以下创建一个组角色:CREATE ROLE group_name;按照习惯,组角色通常不具有 LOGIN 特权,也就是不能作为一个用户登录。例如,我们可以先创建一个组 managers:CREATE ROLE managers;然后,使用与对象授权操作相同的 GRANT 和 REVOKE 语句为组添加和删除成员:GRANT group_name TO user_role, ... ; REVOKE group_name FROM user_role, ... ;我们将用户 tony 添加为组 managers 的成员:opengauss=# GRANT managers TO tony; GRANT ROLE最后一行输出显示了成员角色(tony)所属的组(managers)。也可以将一个组添加为其他组的成员,因为组角色和非组角色并没有什么本质区别。opengauss=# GRANT admin TO managers; GRANT ROLE另外,opengauss不允许设置循环的成员关系,也就是两个角色互相为对方的成员。opengauss=# GRANT managers TO admin; ERROR: role "managers" is a member of role "admin"最后,不能将特殊角色 PUBLIC 设置为任何组的成员。组角色中的成员可以通过以下方式使用该组拥有的特权:• 首先,组中的成员可以通过 SET ROLE 命令将自己的角色临时性“变成”该组角色。此时,当前数据库会话拥有该组角色的权限,而不是登录用户的权限;并且会话创建的任何数据库对象归组角色所有,而不是登录用户所有。• 其次,对于具有 INHERIT 属性的角色,将会自动继承它所属的组的全部特权,包括这些组通过继承获得的特权。考虑以下示例:CREATE ROLE user1 LOGIN INHERIT; CREATE ROLE net_admins NOINHERIT; CREATE ROLE sys_admins NOINHERIT; GRANT net_admins TO user1; GRANT sys_admins TO net_admins;使用角色 user1 登录之后,数据库会话将会拥有 user1 自身的特权和 net_admins 所有的特权,因为 user1“继承”了 net_admins 的特权。但是,会话还不具有 sys_admins 所有的特权,因为即使user1 间接地成为了 sys_admins 的成员,通过 net_admins 获得的成员资格具有 NOINHERIT 属性,也就不会自动继承权限。如果执行了以下语句:SET ROLE net_admins;会话将会拥有 net_admins 所有的特权,但是不会拥有 user1 自身的特权,也不会继承sys_admins 所有的特权。如果执行了以下语句:SET ROLE sys_admins;会话将会拥有 sys_admins 所有的特权,但是不会拥有 user1 或者 net_admins 所有的特权。如果想要恢复初始状态的会话特权,可以执行以下任意语句:SET ROLE user1; SET ROLE NONE; RESET ROLE;在 SQL 标准中,用户和角色之间存在明确的差异,用户不会自动继承特权,而角色会继承特权。opengauss可以实现这种行为,只需要为角色设置 INHERIT 属性,而为用户设置NOINHERIT 属性。但是,为了兼容 8.1 之前的版本实现,PostgreSQL 默认为所有的角色都设置了 INHERIT 属性,这样用户总是会继承它所在组的权限。只有数据库对象上的普通权限可以被继承,角色的 LOGIN、SUPERUSER、CREATEDB 以及 CREATEROLE 属性可以被认为是一些特殊的权限,不会被继承。如果想要使用这些权限,必须使用 SET ROLE 命令设置为具有这些属性的角色。基于上面的示例,我们可以为 net_admins 角色指定 CREATEDB 和 CREATEROLE 属性。ALTER ROLE net_admins CREATEDB, CREATEROLE;然后再使用 user1 连接数据库,会话不会自动具有这些特权,而是需要执行以下命令:SET ROLE net_admins;2.6 删除角色删除角色的语句如下:DROP ROLE name;如果删除的是组角色,该组中的成员关系会自动从组中删除,但是这些成员角色自身不会受到任何影响。以下示例删除了角色 admin:opengauss=# drop role admin; DROP ROLE由于角色可以拥有数据库中的对象,也可以拥有访问其他对象的权限,删除角色通常不仅仅只是一个简单的 DROP ROLE 语句。在删除角色之前,需要删除它所拥有的对象,或者将这些对象重新赋予其他的角色;同时还需要撤销授予该角色的权限。
  • [技术干货] 健康体检项目之运营数据统计
    Apache POI 是用Java编写的免费开源的跨平台的Java API,Apache POI提供API给Java程序对Microsoft Office格式档案读和写的功能,其中使用最多的就是使用POI操作Excel文件。POI为“Poor Obfuscation Implementation”的首字母缩写,意为“简洁版的模糊实现”。一、运营数据统计1.1 需求分析通过运营数据统计可以展示出体检机构的运营情况,包括会员数据、预约到诊数据、热门套餐等信息。本章节就是要通过一个表格的形式来展示这些运营数据。效果如下图:  1.2 完善页面运营数据统计对应的页面为/pages/report_business.html。1.2.1 定义模型数据定义数据模型,通过VUE的数据绑定展示数据<script> var vue = new Vue({ el: '#app', data:{ reportData:{ reportDate:null, todayNewMember :0, totalMember :0, thisWeekNewMember :0, thisMonthNewMember :0, todayOrderNumber :0, todayVisitsNumber :0, thisWeekOrderNumber :0, thisWeekVisitsNumber :0, thisMonthOrderNumber :0, thisMonthVisitsNumber :0, hotSetmeal :[] } } }) </script><div class="box" style="height: 900px"> <div class="excelTitle" > <el-button @click="exportExcel">导出Excel</el-button>运营数据统计 </div> <div class="excelTime">日期:{{reportData.reportDate}}</div> <table class="exceTable" cellspacing="0" cellpadding="0"> <tr> <td colspan="4" class="headBody">会员数据统计</td> </tr> <tr> <td width='20%' class="tabletrBg">新增会员数</td> <td width='30%'>{{reportData.todayNewMember}}</td> <td width='20%' class="tabletrBg">总会员数</td> <td width='30%'>{{reportData.totalMember}}</td> </tr> <tr> <td class="tabletrBg">本周新增会员数</td> <td>{{reportData.thisWeekNewMember}}</td> <td class="tabletrBg">本月新增会员数</td> <td>{{reportData.thisMonthNewMember}}</td> </tr> <tr> <td colspan="4" class="headBody">预约到诊数据统计</td> </tr> <tr> <td class="tabletrBg">今日预约数</td> <td>{{reportData.todayOrderNumber}}</td> <td class="tabletrBg">今日到诊数</td> <td>{{reportData.todayVisitsNumber}}</td> </tr> <tr> <td class="tabletrBg">本周预约数</td> <td>{{reportData.thisWeekOrderNumber}}</td> <td class="tabletrBg">本周到诊数</td> <td>{{reportData.thisWeekVisitsNumber}}</td> </tr> <tr> <td class="tabletrBg">本月预约数</td> <td>{{reportData.thisMonthOrderNumber}}</td> <td class="tabletrBg">本月到诊数</td> <td>{{reportData.thisMonthVisitsNumber}}</td> </tr> <tr> <td colspan="4" class="headBody">热门套餐</td> </tr> <tr class="tabletrBg textCenter"> <td>套餐名称</td> <td>预约数量</td> <td>占比</td> <td>备注</td> </tr> <tr v-for="s in reportData.hotSetmeal"> <td>{{s.name}}</td> <td>{{s.setmeal_count}}</td> <td>{{s.proportion}}</td> <td></td> </tr> </table> </div>1.2.2 发送请求获取动态数据在VUE的钩子函数中发送ajax请求获取动态数据,通过VUE的数据绑定将数据展示到页面<script> var vue = new Vue({ el: '#app', data:{ reportData:{ reportDate:null, todayNewMember :0, totalMember :0, thisWeekNewMember :0, thisMonthNewMember :0, todayOrderNumber :0, todayVisitsNumber :0, thisWeekOrderNumber :0, thisWeekVisitsNumber :0, thisMonthOrderNumber :0, thisMonthVisitsNumber :0, hotSetmeal :[] } }, created() { //发送ajax请求获取动态数据 axios.get("/report/getBusinessReportData.do").then((res)=>{ this.reportData = res.data.data; }); } }) </script>根据页面对数据格式的要求,我们发送ajax请求,服务端需要返回如下格式的数据:{ "data":{ "todayVisitsNumber":0, "reportDate":"2019-04-25", "todayNewMember":0, "thisWeekVisitsNumber":0, "thisMonthNewMember":2, "thisWeekNewMember":0, "totalMember":10, "thisMonthOrderNumber":2, "thisMonthVisitsNumber":0, "todayOrderNumber":0, "thisWeekOrderNumber":0, "hotSetmeal":[ {"proportion":0.4545,"name":"粉红珍爱(女)升级TM12项筛查体检套餐","setmeal_count":5}, {"proportion":0.1818,"name":"阳光爸妈升级肿瘤12项筛查体检套餐","setmeal_count":2}, {"proportion":0.1818,"name":"珍爱高端升级肿瘤12项筛查","setmeal_count":2}, {"proportion":0.0909,"name":"孕前检查套餐","setmeal_count":1} ], }, "flag":true, "message":"获取运营统计数据成功" }1.3 后台代码1.3.1 Controller在ReportController中提供getBusinessReportData方法@Reference private ReportService reportService; ​ /** * 获取运营统计数据 * @return */ @RequestMapping("/getBusinessReportData") public Result getBusinessReportData(){ try { Map<String, Object> result = reportService.getBusinessReport(); return new Result(true,MessageConstant.GET_BUSINESS_REPORT_SUCCESS,result); } catch (Exception e) { e.printStackTrace(); return new Result(true,MessageConstant.GET_BUSINESS_REPORT_FAIL); } }1.3.2 服务接口在health_interface工程中创建ReportService服务接口并声明getBusinessReport方法package com.yunhe.service; import java.util.Map; public interface ReportService { /** * 获得运营统计数据 * Map数据格式: * todayNewMember -> number * totalMember -> number * thisWeekNewMember -> number * thisMonthNewMember -> number * todayOrderNumber -> number * todayVisitsNumber -> number * thisWeekOrderNumber -> number * thisWeekVisitsNumber -> number * thisMonthOrderNumber -> number * thisMonthVisitsNumber -> number * hotSetmeals -> List<Setmeal> */ public Map<String,Object> getBusinessReport() throws Exception; }1.3.3 服务实现类在health_service_provider工程中创建服务实现类ReportServiceImpl并实现ReportService接口package com.yunhe.service; import com.alibaba.dubbo.config.annotation.Service; import com.yunhe.dao.MemberDao; import com.yunhe.dao.OrderDao; import com.yunhe.utils.DateUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.transaction.annotation.Transactional; import java.util.Date; import java.util.HashMap; import java.util.List; import java.util.Map; /** * 统计报表服务 */ @Service(interfaceClass = ReportService.class) @Transactional public class ReportServiceImpl implements ReportService { @Autowired private MemberDao memberDao; @Autowired private OrderDao orderDao; /** * 获得运营统计数据 * Map数据格式: * todayNewMember -> number * totalMember -> number * thisWeekNewMember -> number * thisMonthNewMember -> number * todayOrderNumber -> number * todayVisitsNumber -> number * thisWeekOrderNumber -> number * thisWeekVisitsNumber -> number * thisMonthOrderNumber -> number * thisMonthVisitsNumber -> number * hotSetmeal -> List<Setmeal> */ public Map<String, Object> getBusinessReport() throws Exception{ //获得当前日期 String today = DateUtils.parseDate2String(DateUtils.getToday()); //获得本周一的日期 String thisWeekMonday = DateUtils.parseDate2String(DateUtils.getThisWeekMonday()); //获得本月第一天的日期 String firstDay4ThisMonth = DateUtils.parseDate2String(DateUtils.getFirstDay4ThisMonth()); //今日新增会员数 Integer todayNewMember = memberDao.findMemberCountByDate(today); //总会员数 Integer totalMember = memberDao.findMemberTotalCount(); //本周新增会员数 Integer thisWeekNewMember = memberDao.findMemberCountAfterDate(thisWeekMonday); //本月新增会员数 Integer thisMonthNewMember = memberDao.findMemberCountAfterDate(firstDay4ThisMonth); //今日预约数 Integer todayOrderNumber = orderDao.findOrderCountByDate(today); //本周预约数 Integer thisWeekOrderNumber = orderDao.findOrderCountAfterDate(thisWeekMonday); //本月预约数 Integer thisMonthOrderNumber = orderDao.findOrderCountAfterDate(firstDay4ThisMonth); //今日到诊数 Integer todayVisitsNumber = orderDao.findVisitsCountByDate(today); //本周到诊数 Integer thisWeekVisitsNumber = orderDao.findVisitsCountAfterDate(thisWeekMonday); //本月到诊数 Integer thisMonthVisitsNumber = orderDao.findVisitsCountAfterDate(firstDay4ThisMonth); //热门套餐(取前4) List<Map> hotSetmeal = orderDao.findHotSetmeal(); Map<String,Object> result = new HashMap<>(); result.put("reportDate",today); result.put("todayNewMember",todayNewMember); result.put("totalMember",totalMember); result.put("thisWeekNewMember",thisWeekNewMember); result.put("thisMonthNewMember",thisMonthNewMember); result.put("todayOrderNumber",todayOrderNumber); result.put("thisWeekOrderNumber",thisWeekOrderNumber); result.put("thisMonthOrderNumber",thisMonthOrderNumber); result.put("todayVisitsNumber",todayVisitsNumber); result.put("thisWeekVisitsNumber",thisWeekVisitsNumber); result.put("thisMonthVisitsNumber",thisMonthVisitsNumber); result.put("hotSetmeal",hotSetmeal); return result; } }1.3.4 Dao接口在OrderDao和MemberDao中声明相关统计查询方法package com.yunhe.dao; import com.yunhe.pojo.Order; import java.util.List; import java.util.Map; public interface OrderDao { public void add(Order order); public List<Order> findByCondition(Order order); public Map findById4Detail(Integer id); public Integer findOrderCountByDate(String date); public Integer findOrderCountAfterDate(String date); public Integer findVisitsCountByDate(String date); public Integer findVisitsCountAfterDate(String date); public List<Map> findHotSetmeal(); }package com.yunhe.dao; import com.github.pagehelper.Page; import com.yunhe.pojo.Member; import java.util.List; public interface MemberDao { public List<Member> findAll(); public Page<Member> selectByCondition(String queryString); public void add(Member member); public void deleteById(Integer id); public Member findById(Integer id); public Member findByTelephone(String telephone); public void edit(Member member); public Integer findMemberCountBeforeDate(String date); public Integer findMemberCountByDate(String date); public Integer findMemberCountAfterDate(String date); public Integer findMemberTotalCount(); }1.3.5 Mapper映射文件在OrderDao.xml和MemberDao.xml中定义SQL语句OrderDao.xml:<!--根据日期统计预约数--> <select id="findOrderCountByDate" parameterType="string" resultType="int"> select count(id) from t_order where orderDate = #{value} </select> ​ <!--根据日期统计预约数,统计指定日期之后的预约数--> <select id="findOrderCountAfterDate" parameterType="string" resultType="int"> select count(id) from t_order where orderDate &gt;= #{value} </select> ​ <!--根据日期统计到诊数--> <select id="findVisitsCountByDate" parameterType="string" resultType="int"> select count(id) from t_order where orderDate = #{value} and orderStatus = '已到诊' </select> ​ <!--根据日期统计到诊数,统计指定日期之后的到诊数--> <select id="findVisitsCountAfterDate" parameterType="string" resultType="int"> select count(id) from t_order where orderDate &gt;= #{value} and orderStatus = '已到诊' </select> ​ <!--热门套餐,查询前4条--> <select id="findHotSetmeal" resultType="map"> select s.name, count(o.id) setmeal_count , count(o.id)/(select count(id) from t_order) proportion from t_order o inner join t_setmeal s on s.id = o.setmeal_id group by o.setmeal_id order by setmeal_count desc limit 0,4 </select>MemberDao.xml:<!--根据日期统计会员数,统计指定日期之前的会员数--> <select id="findMemberCountBeforeDate" parameterType="string" resultType="int"> select count(id) from t_member where regTime &lt;= #{value} </select> ​ <!--根据日期统计会员数--> <select id="findMemberCountByDate" parameterType="string" resultType="int"> select count(id) from t_member where regTime = #{value} </select> ​ <!--根据日期统计会员数,统计指定日期之后的会员数--> <select id="findMemberCountAfterDate" parameterType="string" resultType="int"> select count(id) from t_member where regTime &gt;= #{value} </select> ​ <!--总会员数--> <select id="findMemberTotalCount" resultType="int"> select count(id) from t_member </select>二、. 运营数据统计报表导出2.1 需求分析运营数据统计报表导出就是将统计数据写入到Excel并提供给客户端浏览器进行下载,以便体检机构管理人员对运营数据的查看和存档。2.2 提供模板文件本节我们需要将运营统计数据通过POI写入到Excel文件,对应的Excel效果如下:  通过上面的Excel效果可以看到,表格比较复杂,涉及到合并单元格、字体、字号、字体加粗、对齐方式等的设置。如果我们通过POI编程的方式来设置这些效果代码会非常繁琐。在企业实际开发中,对于这种比较复杂的表格导出一般我们会提前设计一个Excel模板文件,在这个模板文件中提前将表格的结构和样式设置好,我们的程序只需要读取这个文件并在文件中的相应位置写入具体的值就可以了。在本章节资料中已经提供了一个名为report_template.xlsx的模板文件,需要将这个文件复制到health_backend工程的template目录中2.3 完善页面在report_business.html页面提供导出按钮并绑定事件<div class="excelTitle" > <el-button @click="exportExcel">导出Excel</el-button>运营数据统计 </div>methods:{ //导出Excel报表 exportExcel(){ window.location.href = '/report/exportBusinessReport.do'; } }2.4 后台代码在ReportController中提供exportBusinessReport方法,基于POI将数据写入到Excel中并通过输出流下载到客户端。/** * 导出Excel报表 * @return */ @RequestMapping("/exportBusinessReport") public Result exportBusinessReport(HttpServletRequest request, HttpServletResponse response){ try{ //远程调用报表服务获取报表数据 Map<String, Object> result = reportService.getBusinessReport(); //取出返回结果数据,准备将报表数据写入到Excel文件中 String reportDate = (String) result.get("reportDate"); Integer todayNewMember = (Integer) result.get("todayNewMember"); Integer totalMember = (Integer) result.get("totalMember"); Integer thisWeekNewMember = (Integer) result.get("thisWeekNewMember"); Integer thisMonthNewMember = (Integer) result.get("thisMonthNewMember"); Integer todayOrderNumber = (Integer) result.get("todayOrderNumber"); Integer thisWeekOrderNumber = (Integer) result.get("thisWeekOrderNumber"); Integer thisMonthOrderNumber = (Integer) result.get("thisMonthOrderNumber"); Integer todayVisitsNumber = (Integer) result.get("todayVisitsNumber"); Integer thisWeekVisitsNumber = (Integer) result.get("thisWeekVisitsNumber"); Integer thisMonthVisitsNumber = (Integer) result.get("thisMonthVisitsNumber"); List<Map> hotSetmeal = (List<Map>) result.get("hotSetmeal"); //获得Excel模板文件绝对路径 String temlateRealPath = request.getSession().getServletContext().getRealPath("template") + File.separator + "report_template.xlsx"; //读取模板文件创建Excel表格对象 XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File(temlateRealPath))); XSSFSheet sheet = workbook.getSheetAt(0); XSSFRow row = sheet.getRow(2); row.getCell(5).setCellValue(reportDate);//日期 ​ row = sheet.getRow(4); row.getCell(5).setCellValue(todayNewMember);//新增会员数(本日) row.getCell(7).setCellValue(totalMember);//总会员数 ​ row = sheet.getRow(5); row.getCell(5).setCellValue(thisWeekNewMember);//本周新增会员数 row.getCell(7).setCellValue(thisMonthNewMember);//本月新增会员数 ​ row = sheet.getRow(7); row.getCell(5).setCellValue(todayOrderNumber);//今日预约数 row.getCell(7).setCellValue(todayVisitsNumber);//今日到诊数 ​ row = sheet.getRow(8); row.getCell(5).setCellValue(thisWeekOrderNumber);//本周预约数 row.getCell(7).setCellValue(thisWeekVisitsNumber);//本周到诊数 ​ row = sheet.getRow(9); row.getCell(5).setCellValue(thisMonthOrderNumber);//本月预约数 row.getCell(7).setCellValue(thisMonthVisitsNumber);//本月到诊数 ​ int rowNum = 12; for(Map map : hotSetmeal){//热门套餐 String name = (String) map.get("name"); Long setmeal_count = (Long) map.get("setmeal_count"); BigDecimal proportion = (BigDecimal) map.get("proportion"); row = sheet.getRow(rowNum ++); row.getCell(4).setCellValue(name);//套餐名称 row.getCell(5).setCellValue(setmeal_count);//预约数量 row.getCell(6).setCellValue(proportion.doubleValue());//占比 } ​ //通过输出流进行文件下载 ServletOutputStream out = response.getOutputStream(); response.setContentType("application/vnd.ms-excel"); response.setHeader("content-Disposition", "attachment;filename=report.xlsx"); workbook.write(out); out.flush(); out.close(); workbook.close(); return null; }catch (Exception e){ return new Result(false, MessageConstant.GET_BUSINESS_REPORT_FAIL,null); } } 
  • OpenGauss的Schema
    创建了数据库之后,还需要创建模式(Schema)才能够存储数据库对象。通常在创建一个新的数据库时,默认会创建一个模式 public。背景信息schema又称作模式。通过管理schema,允许多个用户使用同一数据库而不相互干扰,可以将数据库对象组织成易于管理的逻辑组,同时便于将第三方应用添加到相应的schema下而不引起冲突。管理schema包括:创建schema、使用schema、删除schema、设置schema的搜索路径以及schema的权限控制。注意事项openGauss包含一个或多个已命名数据库。用户和用户组在openGauss范围内是共享的,但是其数据并不共享。任何与服务器连接的用户都只能访问连接请求里声明的那个数据库。一个数据库可以包含一个或多个已命名的schema,schema又包含表及其他数据库对象,包括数据类型、函数、操作符等。同一对象名可以在不同的schema中使用而不会引起冲突。例如,schema1和schema2都可以包含一个名为mytable的表。和数据库不同,schema不是严格分离的。用户根据其对schema的权限,可以访问所连接数据库的schema中的对象。进行schema权限管理首先需要对数据库的权限控制进行了解。不能创建以PG_为前缀的schema名,该类schema为数据库系统预留的。在每次创建新用户时,系统会在当前登录的数据库中为新用户创建一个同名Schema。对于其他数据库,若需要同名Schema,则需要用户手动创建。通过未修饰的表名(名称中只含有表名,没有“schema名”)引用表时,系统会通过search_path(搜索路径)来判断该表是哪个schema下的表。pg_temp和pg_catalog始终会作为搜索路径顺序中的前两位,无论二者是否出现在search_path中,或者出现在search_path中的任何位置。search_path(搜索路径)是一个schema名列表,在其中找到的第一个表就是目标表,如果没有找到则报错。(某个表即使存在,如果它的schema不在search_path中,依然会查找失败)在搜索路径中的第一个schema叫做“当前schema”。它是搜索时查询的第一个schema,同时在没有声明schema名时,新创建的数据库对象会默认存放在该schema下。每个数据库都包含一个pg_catalog schema,它包含系统表和所有内置数据类型、函数、操作符。pg_catalog是搜索路径中的一部分,始终在临时表所属的模式后面,并在search_path中所有模式的前面,即具有第二搜索优先级。这样确保可以搜索到数据库内置对象。如果用户需要使用和系统内置对象重名的自定义对象时,可以在操作自定义对象时带上自己的模式。Schema操作步骤创建管理用户及权限schema执行如下命令来创建一个schema。语法格式创建SCHEMACREATE SCHEMA schema_name [ AUTHORIZATION user_name ] ;修改SCHEMA  修改模式的名称ALTER SCHEMA schema_name RENAME TO new_name;修改模式的所有者。ALTER SCHEMA schema_name OWNER TO new_owner;删除SCHEMA及其对象。DROP SCHEMA schema_name;不要随意删除pg_temp或pg_toast_temp开头的模式,这些模式是系统内部使用的,如果删除,可能导致无法预知的结果。参数说明schema_name模式名称须知: 模式名不能和当前数据库里其他的模式重名。 模式的名称不可以“pg_”开头。取值范围:字符串,要符合标识符的命名规范。AUTHORIZATION user_name指定模式的所有者。当不指定schema_name时,把user_name当作模式名,此时user_name只能是角色名。取值范围:已存在的用户名/角色名。schema_element在模式里创建对象的SQL语句。目前仅支持CREATE TABLE、CREATE VIEW、CREATE INDEX、CREATE PARTITION、CREATE SEQUENCE、CREATE TRIGGER、GRANT子句。子命令所创建的对象都被AUTHORIZATION子句指定的用户所拥有。说明: 如果当前搜索路径上的模式中存在同名对象时,需要明确指定引用对象所在的模式。可以通过命令SHOW SEARCH_PATH来查看当前搜索路径上的模式。根据用户名创建模式。openGauss=# CREATE SCHEMA test AUTHORIZATION user1; CREATE SCHEMA查看当前搜索路径openGauss=# SHOW SEARCH_PATH; search_path ---------------- "$user",public (1 row)更改当前会话的默认Schema。openGauss=# SET SEARCH_PATH TO test1, public; SET删除SCHEMA及其对象。openGauss=# DROP SCHEMA test1; DROP SCHEMA使用以下命令查看现有的schema。openGauss=# SELECT current_schema(); current_schema ---------------- myschema (1 row)使用schema在特定schema下创建对象或者访问特定schema下的对象,需要使用有schema修饰的对象名。该名称包含schema名以及对象名,他们之间用“.”号分开。执行如下命令在myschema下创建mytable表。openGauss=# CREATE TABLE myschema.mytable(id int, name varchar(20)); CREATE TABLE如果在数据库中指定对象的位置,就需要使用有schema修饰的对象名称。执行如下命令查询myschema下mytable表的所有数据。openGauss=# SELECT * FROM myschema.mytable; id | name ----+------ (0 rows)常见错误:错误一:无法删除某个角色1. 检查依赖关系确认角色 test 是哪些模式的所有者:sql复制代码SELECT schema_name FROM information_schema.schemata WHERE schema_owner = 'test';若返回结果包含 test 模式,说明该角色是模式的所有者。2. 转移模式所有权将 test 模式的所有权转移给其他角色(如 admin 或新建角色):-- 方法1:直接转移给现有角色(需目标角色存在)ALTER SCHEMA test OWNER TO admin;再次删除,发现即可删除成功。错误二:删除角色关联所有者、对象较多openGauss=# drop role tony; ERROR: role "tony" cannot be dropped because some objects depend on it DETAIL: owner of database mydb owner of database human_staff 1 object in database human_staff1. 确认角色依赖关系通过错误提示可知,角色tony是以下对象的所有者:• 数据库mydb• 数据库human_staff• 数据库human_staff中的1个对象(如表、模式等)2. 转移数据库所有权若需保留数据库,需将其所有权转移给其他角色(如admin):openGauss=# alter database mydb owner to gauss; openGauss=# alter database human_staff owner to gauss;3. 处理数据库内的对象方法1:转移对象所有权将tony拥有的对象(如表、视图等)的所有权转移给其他角色:-- 切换到目标数据库\c human_staff -- 转移所有对象的所有权(慎用,需超级用户权限) REASSIGN OWNED BY tony TO admin; -- 或逐个转移特定对象 ALTER TABLE <table_name> OWNER TO admin; ALTER SCHEMA <schema_name> OWNER TO admin;4. 撤销角色权限若tony在其他数据库(如postgres)中有权限,需撤销这些权限:sql复制代码-- 切换到postgres数据库\c postgres-- 撤销对特定对象的权限REVOKE ALL ON DATABASE postgres FROM tony;REVOKE ALL ON SCHEMA public FROM tony; -- 示例:撤销对public模式的权限REVOKE ALL ON TABLE pg_class FROM tony; -- 示例:撤销对系统表的权限5. 清理共享依赖若tony的依赖关系涉及共享对象(如角色权限),需检查并清理:sql复制代码-- 查看共享依赖关系(需超级用户)SELECT * FROM pg_shdepend WHERE refobjid = (SELECT oid FROM pg_roles WHERE rolname = 'tony');-- 手动撤销相关权限REVOKE USAGE ON SCHEMA <schema_name> FROM tony; -- 示例:撤销对模式的使用权6. 删除角色完成上述步骤后,尝试再次删除角色:DROP ROLE tony;注意事项1. 权限要求:转移所有权、撤销权限等操作需由超级用户或具备足够权限的角色执行。2. 数据安全:使用DROP OWNED BY或DROP DATABASE前,务必确认无需保留相关数据。3. 系统依赖:若tony是系统管理员(rolsuper或rolsystemadmin),需先转移系统权限。
  • OpenGauss的用户和角色
    openGauss概述openGauss是关系型数据库,采用客户端/服务器,单进程多线程架构;支持单机和一主多备部署方式,同时支持备机可读、双机高可用等特性。openGauss有如下基本功能:1、支持标准SQLopenGauss数据库支持标准的SQL(Structured Query Language,结构化查询语言)。SQL标准是一个国际性的标准,定期会进行更新和演进。SQL标准的定义分成核心特性以及可选特性,绝大部分的数据库都没有100%支撑SQL标准。openGauss数据库支持SQL92/SQL99/SQL2003等,同时支持SQL2011大部分的核心特性,另外还支持部分的可选特性。2、支持标准开发接口openGauss数据库提供业界标准的ODBC(Open Database Connectivity,开放式数据库连接)及JDBC(Java Database Connectivity,java数据库连接)接口,保证用户能将业务快速迁移至openGauss。目前支持标准的ODBC3.5及JDBC4.0接口,其中ODBC能够支持CentOS、openEuler、SUSE、Win32、Win64等平台,JDBC无平台差异。3、混合存储引擎支持openGauss数据库支持行存储引擎、列存储引擎和内存存储引擎等。行存分为“inplace update” 和 “append update”两种模式,前者通过单独的回滚段(undo log)来保留元组的前像以解决读写冲突,可以更自然的支持数据更新;后者将更新记录混杂在数据记录中,通过新旧版本的形式来支持数据更新,对于旧版本需要定期做vacuum操作来支持磁盘空间的回收。列存支持数据快速分析,更适合OLAP(Online Analytical Processing,联机分析处理)业务。内存引擎支持实时数据处理,对有极致性能要求的业务提供支撑。4、事务支持事务支持指的就是系统提供事务的能力,openGauss支持事务的原子性、一致性、隔离性和持久性。事务支持及数据一致性保证是绝大多数数据库的基本功能,只有支持了事务,才能满足事务化的应用需求。用户和角色管理是数据库管理系统中的重要功能,用于管理数据库中的用户和角色,以控制对数据库的访问权限。用户是数据库中的实体,用于标识和管理数据库中的各种操作权限和资源使用权限。而角色是一组权限的集合,可以将一组用户分配到同一个角色上,从而简化权限管理和控制。在openGauss数据库中,用户和角色管理可以通过SQL语句或者openGauss控制台来完成。通过创建、修改、删除用户和角色,可以控制用户的身份验证和访问权限。用户 使用数据库系统服务的个体  职责单一,往往附属于某个组织或部门用户可以做什么  使用工具连接数据库  访问数据库对象  执行SQL语句角色 角色是一组用户的集合,按照数据库系统中承担的责任划分具有不同权限的角色;角色用来作 为权限集合的载体。 ⚫ openGauss 提供了一个隐式定义的拥有所有角色的组PUBLIC,所有创建的用户和角色默 认拥有PUBLIC所拥有的权限。 ⚫ 要撤销或重新授予用户和角色对PUBLIC的权限,可通过在GRANT和REVOKE指定关键字 PUBLIC实现。用户与角色⚫ 用户是实体,角色是行为。 ⚫ 用户可被赋予一个或多个角色。⚫ 角色是一种权限集合,不应该具有登录数据库并执行SQL的能力。 ⚫ 对用户权限的管理,可以简化为对角色权限的管理。 ⚫ 在openGauss中,用户和角色使用相同的操作方式与维护方式。实际使用中的选择在OpenGauss中,CREATE USER更常用于以下场景:需要创建实际登录数据库的账号时为应用程序或个人用户创建账户时而CREATE ROLE通常用于:创建权限组(如read_only_role, write_role等)实现权限继承和组合作为模板角色语法CREATE USER name [ [ WITH ] option [ ... ] ] 这里 option 可以是: SUPERUSER | NOSUPERUSER | CREATEDB | NOCREATEDB | CREATEROLE | NOCREATEROLE | INHERIT | NOINHERIT | LOGIN | NOLOGIN | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' | IN ROLE role_name [, ...] | IN GROUP role_name [, ...] | ROLE role_name [, ...] | ADMIN role_name [, ...] | USER role_name [, ...] | SYSID uid修改角色/用户ALTER USER role_specification [ WITH ] option [ ... ] 其中 option 可以是: SUPERUSER | NOSUPERUSER | CREATEDB | NOCREATEDB | CREATEROLE | NOCREATEROLE | INHERIT | NOINHERIT | LOGIN | NOLOGIN | REPLICATION | NOREPLICATION | BYPASSRLS | NOBYPASSRLS | CONNECTION LIMIT connlimit | [ ENCRYPTED ] PASSWORD 'password' | PASSWORD NULL | VALID UNTIL 'timestamp' ALTER USER name RENAME TO new_name ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter { TO | = } { value | DEFAULT } ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] SET configuration_parameter FROM CURRENT ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET configuration_parameter ALTER USER { role_specification | ALL } [ IN DATABASE database_name ] RESET ALL删除角色/用户DROP USER [ IF EXISTS ] name [, ...]查询类操作:  openGauss的用户、角色属性维护在pg_authid系统表中,pg_user、pg_roles视图也可以查询 用户、角色信息。  使用\d命令查看pg_authid表详细信息。  使用select命令查询pg_authid中的相关信息。角色属性角色可以拥有属性,属性确定了角色拥有的特权,并且在登录时与客户端认证系统进行交互。常见的角色属性包括:• 登录特权,只有具有 LOGIN 属性的角色才能连接数据库。具有 LOGIN 角色的用户可以被看作一个“数据库用户”。使用以下语句创建具有登录特权的角色:CREATE ROLE name LOGIN;CREATE USER name;CREATE USER 与 CREATE ROLE 都可以用于创建角色,只不过 CREATE USER 默认包含了 LOGIN 选项,而 CREATE ROLE 没有。• 超级用户,数据的超级用户可以避开所有的权限检查,只验证登录权限。因此,这是一个很危险的特权,使用时需要特别小心;最好在日常的操作中避免使用超级用户。使用以下命令创建一个新的超级用户:CREATE ROLE name SUPERUSER;只有超级用户才能创建其他的超级用户。• 创建数据库,只有明确授权的角色才能够创建数据库(超级用户除外,因为他们可以避开权限检查)。使用以下语句创建一个具有数据库创建特权的角色:CREATE ROLE name CREATEDB;• 创建角色,只有明确授权的角色才能够创建其他角色(超级用户除外,因为他们可以避开权限检查)。使用以下命令创建一个具有角色创建特权的角色:CREATE ROLE name CREATEROLE;具有 CREATEROLE 特权的角色还可以修改或删除其他角色,以及为这些角色授予或者撤销成员角色。但是,针对超级用户的创建、修改、删除,以及它的成员变更,需要超级用户特权;CREATEROLE 特权无法针对超级用户执行这些操作。• 启动复制,只有明确授权的角色才能够启动流复制(超级用户除外,因为他们可以避开权限检查)。用于流复制的角色还需要拥有 LOGIN 特权。使用以下语句创建可以用于流复制的角色:CREATE ROLE name REPLICATION LOGIN;• 密码,只有当用户连接数据库使用的客户端认证方法要求提供密码时,密码属性才有意义。password 和 md5 认证方法需要使用密码。数据库的密码与操作系统的密码相互独立。使用以下语句在创建角色时指定密码:CREATE ROLE name PASSWORD 'string';我们在创建角色时,可以根据需要指定某些属性。例如,以下命令创建一个具有登录特权的角色 tony,并且为它指定了密码以及密码过期时间:CREATE ROLE tony WITH LOGIN PASSWORD 'Pass2019' VALID UNTIL '2020-01-01';-- CREATE USER tony WITH PASSWORD 'Pass2019' VALID UNTIL '2020-01-01';使用该用户连接到 postgres 数据库:[root@centos7 ~]# psql -h 192.168.56.103 -p 5432 -U tony postgresPassword for user tony:psql (14.2)Type "help" for help.postgres=> \cYou are now connected to database "postgres" AS user "tony".psql 命令行工具支持许多选项,-h 表示数据库服务器的地址,-p 表示服务的监听端口,-U表示登录使用的用户名,最后的 postgres 代表要连接的数据库。详细的命令行参数可以使用 psql--help 查看。以下命令创建一个管理角色 admin,它具有创建数据库和创建角色的特权:opengauss=# CREATE ROLE admin CREATEDB CREATEROLE; CREATE ROLE在实践中,最好创建一个拥有 CREATEDB 和 CREATEROLE 特权,但不具有超级用户特权的管理角色,然后使用该角色执行日常的数据库和角色的管理。这种方式可以避免过度使用超级用户可能带来的风险。一个角色被创建之后,可以通过 ALTER ROLE 语句修改它的属性。例如,以下命令可以撤销角色 admin 创建角色的特权:opengauss=# ALTER ROLE admin NOCREATEROLE; ALTER ROLE2.3 对象授权当我们使用新创建的用户(tony)连接数据库(hrdb)之后,执行以下查询语句:hrdb=> SELECT * FROM employees; ERROR: permission denied for table employees以上语句执行错误是因为用户没有相应对象上的访问权限。opengauss使 GRANT 语句进行数据库对象的授权操作。以表为例,基本的授权语法如下:GRANT privilege_list | ALL ON [ TABLE ] table_name TO role_name;其中,privilege_list 权限列表可以是 SELECT、INSERT、UPDATE、DELETE、TRUNCATE等,ALL 表示表上的所有权限。例如,使用 gauss用户连接 hrdb 数据库后执行以下语句:hrdb=# GRANT SELECT, INSERT, UPDATE, DELETE hrdb-# ON employees, departments, jobs hrdb-# TO tony;GRANT该语句将 employees、departments 和 jobs 表上的增删改查权限授予了 tony 用户。此时 tony用户就可以访问这些表中的数据:hrdb=> SELECT first_name, last_name FROM employees;对表进行授权的 GRANT 语句还支持一些其他选项:GRANT privilege_list | ALL ON ALL TABLES IN SCHEMA schema_name TO role_name;ALL TABLES IN SCHEMA 表示某个模式中的所有表,可以方便批量授权操作。例如:hrdb=# GRANT SELECT hrdb-# ON ALL TABLES IN SCHEMA public hrdb-# TO tony;GRANT该语句将 public 模式中所有表的查询权限授予 tony 用户。我们也可以在 GRANT 语句的最后指定一个 WITH GRANT OPTION,意味着被授权的角色可以将该权限授权其他角色。例如:hrdb=# GRANT SELECT, INSERT, UPDATE, DELETE hrdb-# ON employees, departments, jobs hrdb-# TO tony WITH GRANT OPTION;此时,tony 用户不但拥有这些表上的访问权限,还可以将这些权限授予其他角色。除了授权表的访问权限之外,GRANT 语句还支持字段、视图、序列、数据库、函数、过程、模式等对象的授权操作。2.4 撤销授权与授权操作相反的就是撤销权限,opengauss使 REVOKE 语句撤销数据库对象上的权限。同样以表为例,基本的撤销授权语句如下:REVOKE privilege_list | ALL ON TABLE table_name FROM role_name;其中的参数和 GRANT 语句一致。例如:hrdb=# REVOKE SELECT, INSERT, UPDATE, DELETE hrdb-# ON employees, departments, jobs hrdb-# FROM tony;REVOKE该语句撤销了用户 tony 访问 employees、departments 以及 jobs 表的权限。REVOKE 语句也支持对某个模式中的所有对象进行操作:REVOKE privilege_list | ALL ON ALL TABLES IN SCHEMA schema_name FROM role_name;例如以下语句撤销了用户 tony 在 public 模式中所有表上的查询权限:hrdb=# REVOKE SELECT hrdb-# ON ALL TABLES IN SCHEMA public hrdb-# FROM tony;REVOKE与 GRANT 语句对应,REVOKE 语句还支持字段、视图、序列、数据库、函数、过程、模式等对象的撤销授权操作。2.5 角色成员在现实的环境中,管理员通常需要管理大量的用户和对象权限。为了便于权限管理,减少复杂度,可以将用户进行分组,然后以组为单位进行权限的授予和撤销操作。为此,opengauss引入了组(group)角色的概念。具体来说,就是创建一个代表组的角色,然后将该组的成员资格授予其他用户,让其成为该组的成员。首先,使用以下创建一个组角色:CREATE ROLE group_name;按照习惯,组角色通常不具有 LOGIN 特权,也就是不能作为一个用户登录。例如,我们可以先创建一个组 managers:CREATE ROLE managers;然后,使用与对象授权操作相同的 GRANT 和 REVOKE 语句为组添加和删除成员:GRANT group_name TO user_role, ... ; REVOKE group_name FROM user_role, ... ;我们将用户 tony 添加为组 managers 的成员:opengauss=# GRANT managers TO tony; GRANT ROLE最后一行输出显示了成员角色(tony)所属的组(managers)。也可以将一个组添加为其他组的成员,因为组角色和非组角色并没有什么本质区别。opengauss=# GRANT admin TO managers; GRANT ROLE另外,opengauss不允许设置循环的成员关系,也就是两个角色互相为对方的成员。opengauss=# GRANT managers TO admin; ERROR: role "managers" is a member of role "admin"最后,不能将特殊角色 PUBLIC 设置为任何组的成员。组角色中的成员可以通过以下方式使用该组拥有的特权:• 首先,组中的成员可以通过 SET ROLE 命令将自己的角色临时性“变成”该组角色。此时,当前数据库会话拥有该组角色的权限,而不是登录用户的权限;并且会话创建的任何数据库对象归组角色所有,而不是登录用户所有。• 其次,对于具有 INHERIT 属性的角色,将会自动继承它所属的组的全部特权,包括这些组通过继承获得的特权。考虑以下示例:CREATE ROLE user1 LOGIN INHERIT; CREATE ROLE net_admins NOINHERIT; CREATE ROLE sys_admins NOINHERIT; GRANT net_admins TO user1; GRANT sys_admins TO net_admins;使用角色 user1 登录之后,数据库会话将会拥有 user1 自身的特权和 net_admins 所有的特权,因为 user1“继承”了 net_admins 的特权。但是,会话还不具有 sys_admins 所有的特权,因为即使user1 间接地成为了 sys_admins 的成员,通过 net_admins 获得的成员资格具有 NOINHERIT 属性,也就不会自动继承权限。如果执行了以下语句:SET ROLE net_admins;会话将会拥有 net_admins 所有的特权,但是不会拥有 user1 自身的特权,也不会继承sys_admins 所有的特权。如果执行了以下语句:SET ROLE sys_admins;会话将会拥有 sys_admins 所有的特权,但是不会拥有 user1 或者 net_admins 所有的特权。如果想要恢复初始状态的会话特权,可以执行以下任意语句:SET ROLE user1; SET ROLE NONE; RESET ROLE;在 SQL 标准中,用户和角色之间存在明确的差异,用户不会自动继承特权,而角色会继承特权。opengauss可以实现这种行为,只需要为角色设置 INHERIT 属性,而为用户设置NOINHERIT 属性。但是,为了兼容 8.1 之前的版本实现,PostgreSQL 默认为所有的角色都设置了 INHERIT 属性,这样用户总是会继承它所在组的权限。只有数据库对象上的普通权限可以被继承,角色的 LOGIN、SUPERUSER、CREATEDB 以及 CREATEROLE 属性可以被认为是一些特殊的权限,不会被继承。如果想要使用这些权限,必须使用 SET ROLE 命令设置为具有这些属性的角色。基于上面的示例,我们可以为 net_admins 角色指定 CREATEDB 和 CREATEROLE 属性。ALTER ROLE net_admins CREATEDB, CREATEROLE;然后再使用 user1 连接数据库,会话不会自动具有这些特权,而是需要执行以下命令:SET ROLE net_admins;2.6 删除角色删除角色的语句如下:DROP ROLE name;如果删除的是组角色,该组中的成员关系会自动从组中删除,但是这些成员角色自身不会受到任何影响。以下示例删除了角色 admin:opengauss=# drop role admin; DROP ROLE由于角色可以拥有数据库中的对象,也可以拥有访问其他对象的权限,删除角色通常不仅仅只是一个简单的 DROP ROLE 语句。在删除角色之前,需要删除它所拥有的对象,或者将这些对象重新赋予其他的角色;同时还需要撤销授予该角色的权限。
  • openGauss下的操作指令
    openGauss 是一款全面友好开放,携手伙伴共同打造的企业级开源关系型数据库。openGauss采用木兰宽松许可证v2发行,提供面向多核架构的极致性能、全链路的业务、数据安全、基于AI的调优和高效运维的能力。openGauss深度融合华为在数据库领域多年的研发经验,结合企业级场景需求,持续构建竞争力特性。同时,openGauss也是一个开源、免费的数据库平台,鼓励社区贡献、合作。数据库作为信息系统基础底座软件,在大数据背景下,数据库的数据量和节点规模日益增长,数据库使用方越来越看重系统运行是否稳定、安全和高效,这也使数据库自身的运行与维护的要求也随之增高。是否拥有成熟健全的运行维护体系,支撑团队的数据库运维管理能力是否足够专业化和标准化,这都将影响和制约着整个企业信息化发展的步伐。数据库运维一般会涉及到数据存储方案设计、数据库表设计、索引设计和SQL优化等,另外还包括对数据库进行变更、监控、备份、高可用设计等工作。本文将从数据库运维的角度简单介绍一下openGauss在日常运维工作中常用的操作命令,以便能够帮助大家轻松使用openGauss数据库。常用运维相关命令第一组:openGauss启停高斯数据库的启动/停止/重启指令:gs_ctl start -D /home/gauss/openGauss/data/ gs_ctl stop-D /home/gauss/openGauss/data/ gs_ctl restart -D /home/gauss/openGauss/data/#查看进程ps ux |grep gauss#查看端口号netstat -lntup|grep gauss ss -lntup|grep gauss第二组:openGauss库表指令#进入到高斯数据库使用jack用户连接到远程主机postgres数据库的15400端口。复杂格式gsql -h 10.180.123.163 -d postgres -U jack -p 15400[gauss@server1 ~]$ gsql -d postgres -p 5432 gsql ((openGauss-lite 6.0.1 build 84c20a90) compiled at 2025-01-17 17:49:04 commit 0 last mr release) Non-SSL connection (SSL connection is recommended when requiring high-security) Type "help" for help. openGauss=##查看相应的数据库openGauss=# \l List of databases Name | Owner | Encoding | Collate | Ctype | Access privileges -------------+-------+----------+-------------+-------------+------------------- human_staff | gauss | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | postgres | gauss | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | template0 | gauss | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/gauss + | | | | | gauss=CTc/gauss template1 | gauss | UTF8 | zh_CN.UTF-8 | zh_CN.UTF-8 | =c/gauss + | | | | | gauss=CTc/gauss (4 rows)#库的删除drop database human_staff; DROP DATABASE#创建数据库openGauss=# create database human_staff; CREATE DATABASE#和\l 类似 查看库指令openGauss=# SELECT datname FROM pg_database; datname ------------- template1 human_staff template0 postgres (4 rows)#进入到human_staffopenGauss=# \c human_staff Non-SSL connection (SSL connection is recommended when requiring high-security) You are now connected to database "human_staff" as user "gauss". #下面的指令不会成功,不是mysql的指令。 human_staff=# select * from tables;第三#查看表信息#human_staff=# \dt No relations found.human_staff=# create table users(id int,uname varchar(50)); CREATE TABLE human_staff=# \dt List of relations Schema | Name | Type | Owner | Storage --------+-------+-------+-------+---------------------------------- public | users | table | gauss | {orientation=row,compression=no} (1 row) human_staff=# insert into users values(1,'tom'); INSERT 0 1 human_staff=# select * from users; id | uname ----+------- 1 | tom (1 row)  #变量的设置#设置变量 openGauss=# \set dbname2 shopdb #显示变量 openGauss=# \echo :dbname2 shopdb #删除变量 openGauss=# \unset dbname2#解决:^A H问题; bash # 在root用户下,安装rlwrap sudo yum install rlwrap # 使用rlwrap运行gsql rlwrap gsql -d postgres -p 5432第三组:openGauss表数据管理需要提前创建库omm1、创建一张表 products字段名数据类型含义product_idinteger产品编号product_namechar(30)产品名categorychar(20)种类----建表语句create table products ( product_id integer, product_name char(30), category char(20) ) ;----查看表的结构omm=# \d products2、向表中插入数据,分别采用一次插入一条和一次插入多条记录的方式insert into products(product_id,product_name,category) values (1502, ‘olympus camera’, ‘electrncs’); insert into products(product_id,product_name,category) values (1601,‘lamaze’,‘toys’), (1700,‘wait interface’,‘Books’), (1666,‘harry potter’,‘toys’);3、查询表中所有记录及记录数select count(*) from products; select * from products;4、查询表中所有category记录,并将查询结果按升序排序select category from products order by category asc;5、查询表中category为toys的记录select * from products where category = ‘toys’;6、更改表中某个字段的值update products set product_name=‘camera’ where product_id=1502;select * from products;6、删除表productsdrop table products; select * from products;总结openGauss数据库作为一款基于SQL标准的关系型数据库管理系统,支持广泛的SQL指令进行数据操作、查询、管理以及权限控制。OpenGauss提供面向多核的极致性能、全链路的业务和数据安全、基于AI的调优和高效运维的能力让我受益匪浅。尤其是OpenGauss在AI自治方面的能力真是令人惊喜。自调优、自诊断自愈、自组装这三大自治简直是所有dba的福音。
  • [技术干货] 华为开发者空间-GaussDB免费领取与实践
     📰 GaussDB简介GaussDB是华为自主创新研发的分布式关系型数据库。该产品支持分布式事务,同城跨AZ部署,数据0丢失,支持1000+的扩展能力,PB级海量存储。同时拥有云上高可用,高可靠,高安全,弹性伸缩,一键部署,快速备份恢复,监控告警等关键能力,能为企业提供功能全面,稳定可靠,扩展性强,性能优越的企业级数据库服务。高安全GaussDB拥有TOP级的商业数据库安全特性,能够满足政企和金融级客户的核心安全诉求。安全特性包括:数据动态脱敏,行级访问控制,密态计算。健全的工具与服务化能力GaussDB已经拥有华为云,商用服务化部署能力,同时支持DAS、DRS等生态工具。有效保障用户开发、运维、优化、监控、迁移等日常工作需要。全栈自研GaussDB基于鲲鹏生态,是当前国内唯一能够做到全栈自主可控的国产品牌。同时GaussDB能够基于硬件优势在底层不断进行优化,提升产品综合性能。开源生态GaussDB已经支持开源社区。🚀 领取免费版/购买付费版介绍和指引01 领取免费版GaussDB免费报名领取GaussDB在线试用版(2025年06月 21日 - 2025年 12月 31日),有1000个名额,数量有限。领取与使用方法见如下案例内容:华为开发者空间-GaussDB云数据库领取与使用指导02 购买付费版GaussDB购买GaussDB数据库实例可参考购买付费版GaussDB✍️ GaussDB数据库实操📚 01 GaussDB之基本SQL语法实践SQL是用于访问和处理数据库的标准计算机语言,SQL语言由用于处理数据库和数据库对象的命令和函数组成,GaussDB默认支持SQL:2016的大部分特性。GaussDB提供界面化工具DAS连接数据实例,执行SQL语句完成数据库用户、数据库、数据表以及记录的增删改查等SQL操作实践:基于开发者空间GaussDB数据库完成SQL基本语法实践 📚 02 基于GaussDB数据库PL/pgSQL的实践PLPGSQL是一种过程化SQL语言(Procedural Language/Postgres SQL),PL/pgSQL是PostgreSQL数据库对SQL扩展的高阶SQL。在普通SQL语句的使用上增加了编译语言的特点,所以PL/pgSQL就是把数据操作和查询语句组织在PL/pgSQL代码的过程性单元中,通过逻辑判断、循环等操作实现复杂的功能或者计算的程序语言。通过实际操作,让大家深入了解如何利用 PL/pgSQL 开发并部署一个函数功能模块。在这个过程中,大家将学习到从函数创建、数据批量读取到SQL程序编写以及与触发器集成等一系列关键步骤,从而掌握 PL/pgSQL 的基本使用方法,体验其在应用开发中的优势。实践:GaussDB数据库之PL/pgSQL实践一本案例详细介绍了PL/pgSQL的变量,条件控制,循环控制,ERROR抓取,NULL语句,匿名块与存储过程等知识在GaussDB中的应用。实践:GaussDB数据库之PL/pgSQL实践二本实例详细介绍了PL/pgSQL的游标,自定义函数,触发器,信息打印,常用SQL在GaussDB中的实践。 📚 03 通过三方驱动连接GaussDB数据库完成数据开发(需要购买EIP)GaussDB支持通过JDBC、ODBC、libpq、Psycopg、Go、ecpg等接口来连接数据库并进行操作。Psycopg是一种用于执行SQL语句的PythonAPI,可以为GaussDB数据库提供统一访问接口,应用程序可基于它进行数据操作。Psycopg3是对libpq的封装,主要使用C语言实现,既高效又安全。它具有客户端游标和服务器端游标、异步通信和通知、支持“COPY TO/COPY FROM”功能。支持多种类型Python开箱即用,适配GaussDB数据类型。实践:在开发者空间使用gaussdb-python连接GaussDBODBC(Open Database Connectivity,开放数据库互连)是由Microsoft公司基于X/OPEN CLI提出的以C/C++语言来访问数据库的应用程序编程接口。它提供了一种统一的方法,让应用程序可以访问各种数据库管理系统(DBMS),而不用考虑具体的数据库类型或者操作系统平台。ODBC允许应用程序使用SQL来查询、插入、更新和删除数据库中的数据。应用程序通过ODBC提供的API与数据库进行交互,增强了应用程序的可移植性、扩展性和可维护性。实践:基于开发者空间编写ODBC应用程序操作GaussDB数据库 📚 04 基于GaussDB数据库实现业务场景的实践(需要购买EIP)GaussDB广泛用于金融、政府、电商等领域,能够支持各领域高并发、高可用等业务场景。Django是一个高级的Python Web应用框架,可以快速开发安全和可维护的网站。由经验丰富的开发者构建,Django负责处理网站开发中麻烦的部分,可以专注于编写应用程序,而无需重新开发。GaussDB数据库支持对接Django框架,作为Django WEB项目的数据库存取数据。实践:在华为开发者空间云开发环境部署Django与GaussDB对接的实践应用 📚 05 GaussDB之分区表和AI特性实践分区表在数据库中使用广泛,尤其在数据库大表中对数据拆分,分表等领域,利用分区把表数据划分多个不同数据文件,利用表空间可把不同分区的表数据分布在不同磁盘,可以充分利用磁盘I/O和数据文件并行读取,以分区方式优化索引起到查询性能提升(因为不同分区会使优化器对执行计划剪枝)。GaussDB开发并优化项目中业务应用的SQL语句等功能。在这个过程中,大家将学习到从AI函数的引用、AI功能的原理以及分析AI能力等一系列关键步骤,从而掌握 GaussDB-AI的基本使用方法,体验其在应用开发中的优势。实践:GaussDB之分区表的优化与应用本案例详细讲述了大数据量的表在查询时,针对查询条件和数据特征,给大表数据做物理上的分区存储,基于不同表空间,利用多磁盘IO并行读写数据,优化并提升性能。实践:GaussDB-AI特性之索引智能推荐本案例详细讲述了AI特性里的索引智能推荐功能,根据GaussDB提供的gs_index_advise()接口,根据实际的SQL执行计划,智能推荐出更好的索引并大大优化SQL性能。
  • [交流吐槽] 尝试发帖
    尝试发帖,完成一个测试任务
  • [技术干货] 企业级数据库解决方案 - OpenGauss主备系统在开发者空间的落地实践
    📰 案例概览本案例以OpenGauss示例,借助开发者空间云主机提供的OpenEuler系统环境,下载OpenGauss源代码,以云主机作为开发环境适配,编译安装OpenGauss数据库,并部署OpenGuass一主一备集中式集群系统。🚀 背景与简介OpenGauss是一项基于华为开源社区,从GaussDB分布式数据库中DN节点独立出来的开源项目。OpenGauss作为GaussDB单机集中式开源数据库,具备数据库系统所有功能。GaussDB集中式集群系统即为GaussDB For OpenGauss,其与开源项目的主要区别是GaussDB For OpenGauss在OpenGauss基础上加入一些商业特性功能(Oracle语法兼容,数据安全,加密传输等商业特性支持)。通过实际操作,让大家深入了解如何云主机环境编译安装OpenGuass数据库,并部署集中式主备集群。在这个过程中,大家将学习到从数据库源码编译OpenGauss安装包、数据库应用安装部署以及集中式(一主一备两节点)适配部署等一系列关键步骤,从而掌握 OpenGauss数据库的编译、安装、集中式部署适配的基本使用方法,体验其在应用开发中的优势。案例优势:直接在华为云开发者空间的云主机中配置研发环境,自行根据gitee代码仓库编译安装最新代码版本,不受机器和地理影响,只要有网络即可在一个稳定独属自己的环境中测试OpenGauss数据库功能和使用。🥏 案例流程  🕹️ 流程说明从Gitee下载OpenGauss源代码。部署编译环境并安装OpenGaussDB。部署1主1备集中式数据库集群系统。✍️ 案例实操🎉 基于开发者空间部署OpenGauss主备集中式数据库系统  👈👈👈  体验完整案例,请点击这里进行查看下载OpenGaussDB源代码。适配数据库开发环境。编译生成数据库安装包安装OpenGaussDB数据库系统。部署1主1备双节点集中式集群。测试主备库数据同步。停止数据库集群服务。🌈 案例最终结果  
  • [问题求助] openEuler22.03LTSSP4装openGauss6.0.0的初始化时报:no data was returned by command ""/opt/software/openGauss/openGauss/bin/gaus..
    不是真实的机器是虚拟机,使用QEMU创建的虚拟机因为我是为了和工作环境的机器保持一致,所以没用x86的镜像,也不知道x86的是不是就可以装好…iso为:openEuler-22.03-LTS-SP4-aarch64-dvd.isoopenGauss安装包为:openGauss-Server-6.0.0-openEuler22.03-aarch64.tar.bz2安装路径:/opt/software/openGauss/openGauss安装包路径:/opt/software/openGauss/install目前的情况是:完整报错:[omm@openEuler openGauss]$ gs_initdb -D /opt/software/openGauss/openGauss/data/single_node --nodename=single_node -w ******* no data was returned by command ""/opt/software/openGauss/openGauss/bin/gaussdb" -V" The program "gaussdb" is needed by gs_initdb but was not found in the same directory as "/opt/software/openGauss/openGauss/bin/gs_initdb". Check your installation. 权限情况:/opt drwxr-xr-x. 3 root root 4096 7月 1 13:44 opt /opt/software drwxrwsr-x. 3 root sftgrp 4096 7月 1 13:44 software /opt/software/openGauss drwxrwsr-x. 4 omm omm 4096 7月 1 13:44 openGauss /opt/software/openGauss/install&openGauss drwxrwsr-x. 2 root sftgrp 4096 7月 1 14:02 install drwx--S---. 10 omm omm 4096 7月 1 15:58 openGauss /opt/software/openGauss/openGauss/* [omm@openEuler openGauss]$ ll 总用量 36 drwxr-s---. 2 omm omm 4096 9月 29 2024 bin drwxrwsr-x. 2 omm omm 4096 7月 2 09:30 data drwxr-s---. 3 omm omm 4096 9月 29 2024 etc drwxr-s---. 3 omm omm 4096 9月 29 2024 include drwxr-s---. 4 omm omm 4096 9月 29 2024 jre drwxr-s---. 5 omm omm 4096 9月 29 2024 lib drwxr-s---. 5 omm omm 4096 9月 29 2024 share drwxr-s---. 2 omm omm 4096 7月 2 09:11 simpleInstall -rw-r-----. 1 omm omm 47 9月 29 2024 version.cfg /opt/software/openGauss/openGauss/bin/* [omm@openEuler bin]$ ll 总用量 151452 -rw-r--r--. 1 omm omm 7297 9月 29 2024 alarmItem.conf -rwxr-xr-x. 1 omm omm 5891 9月 29 2024 bind_net_irq.sh -r--r--r--. 1 omm omm 58784 9月 29 2024 cluster_guc.conf -rw-r-----. 1 omm omm 6455 9月 29 2024 dms_contrl.sh -rw-r-----. 1 omm omm 9306 9月 29 2024 dss_clear.sh -rwxr-x---. 1 omm omm 5392744 9月 29 2024 dsscmd -rw-r-----. 1 omm omm 11803 9月 29 2024 dss_contrl.sh -rwxr-x---. 1 omm omm 4724168 9月 29 2024 dssserver -rwxr-x---. 1 omm omm 1838040 9月 29 2024 ecpg -rwxr-x---. 1 omm omm 134792 9月 29 2024 encrypt -rwxr-x---. 1 omm omm 131679648 9月 29 2024 gaussdb -rwxr-x---. 1 omm omm 267040 9月 29 2024 gs_assessment -rwxr-x---. 1 omm omm 207416 9月 29 2024 gs_basebackup -rwxr-x---. 1 omm omm 265360 9月 29 2024 gs_cgroup -rwxr-x---. 1 omm omm 470752 9月 29 2024 gs_ctl -rwxr-x---. 1 omm omm 1121 9月 29 2024 gs_dbmind -rwxr-x---. 1 omm omm 661664 9月 29 2024 gs_dump -rwxr-x---. 1 omm omm 267456 9月 29 2024 gs_dumpall lrwxrwxrwx. 1 omm omm 7 9月 29 2024 gs_encrypt -> gaussdb -rwxr-x---. 1 omm omm 332520 9月 29 2024 gs_guc -rwxr-x---. 1 omm omm 279152 9月 29 2024 gs_initdb -rwxr-xr-x. 1 omm omm 30469 9月 29 2024 gs_plan_simulator.sh -rwxr-x---. 1 omm omm 673000 9月 29 2024 gs_probackup -rwxr-x---. 1 omm omm 791888 9月 29 2024 gsql -rwxr-x---. 1 omm omm 332832 9月 29 2024 gs_restore -rwxr-x---. 1 omm omm 206920 9月 29 2024 gs_retrieve lrwxrwxrwx. 1 omm omm 13 9月 29 2024 gs_tar -> gs_basebackup -rwxr-x---. 1 omm omm 140520 9月 29 2024 gstrace ......gs_initdb和gaussdb两个文件都是有的环境变量配置是这样[omm@openEuler bin]$ cat /home/omm/.bashrc # Source default setting [ -f /etc/bashrc ] && . /etc/bashrc # User environment PATH export PATH # openGauss PATH export GAUSSHOME=/opt/software/openGauss/openGauss export PATH=$GAUSSHOME/bin:$PATH export LD_LIBRARY_PATH=$GAUSSHOME/lib:$LD_LIBRARY_PATH export GS_CLUSTER_NAME=dbCluster输出也是可以输出的:[omm@openEuler bin]$ echo $GAUSSHOME /opt/software/openGauss/openGauss ######分隔 [omm@openEuler bin]$ gsql -V gsql (openGauss 6.0.0 build aee4abd5) compiled at 2024-09-29 19:31:41 commit 0 last mr ######分隔 [omm@openEuler bin]$ /opt/software/openGauss/openGauss/bin/gaussdb -V gaussdb (openGauss 6.0.0 build aee4abd5) compiled at 2024-09-29 19:31:41 commit 0 last mr然后一些别的参数啥的也检查了:##防火墙 ####### [omm@openEuler bin]$ systemctl status firewalld ○ firewalld.service - firewalld - dynamic firewall daemon Loaded: loaded (/usr/lib/systemd/system/firewalld.service; disabled; vendor preset: enabled) Active: inactive (dead) Docs: man:firewalld(1) ##RemoveIPC ####### [omm@openEuler bin]$ loginctl show-session | grep RemoveIPC RemoveIPC=no [omm@openEuler bin]$ systemctl show systemd-logind | grep RemoveIPC RemoveIPC=no ##ulimit ####### [omm@openEuler bin]$ ulimit -n 100000 一头雾水,三四天了一直是这个问题,之前以为是数据库没装好,后来发现装好了只是初始化不行…
  • [课程学习] 高校信创数据库人才培养交流
    2025年6月6日下午在天津职业技术师范大学的高校信创数据库人才培养创新与变革暨天职师大数据库教学平台国产化替代院长峰会上做了武汉大学开源数据库人才教育的交流报告,重点介绍了特软班在数据库课程实践环节使用openGauss的情况。新闻报道https://xxxy.tute.edu.cn/info/1141/12772.htm报告PPT链接: https://pan.baidu.com/s/1wzhjNX39qK92LcS66VG8_w?pwd=48hf 提取码: 48hf
  • [数据库类] 使用docker离线私有化部署openGauss_7.0.0-RC1极简版,如何兼容mysql
    因项目需私有化部署到内网,不允许连接网络。考虑使用docker的方式部署openGauss_7.0.0-RC1 极简版,有可能兼容mysql吗?
  • [问题求助] opengauss物理备份 gs_probackup命令相关提问
    各位大神们好,小白初次接触 opengauss,对于 gs_probackup 物理备份命令中 -w --no-password 参数有些疑问官网文档里是这么说的:-w, --no-password不出现输入密码提示。如果主机要求密码认证并且密码没有通过其它形式给出,则连接尝试将会失败。 该选项在批量工作和不存在用户输入密码的脚本中很有帮助。 我想知道的是这其中的 “密码没有通过其它形式给出”是何含义?是 opengauss 的启动用户需要创建密码文件吗?还是要用 gs_probackup set-config将密码写入配置?如果需要以免交互的形式备份数据库的话,应该怎么做?麻烦各位大神答疑解惑了
  • [技术干货] Linux系统中MySQL的备份机制
    Linux系统中MySQL的备份机制在Linux系统中,MySQL数据库的备份机制是确保数据安全性和可靠性的重要手段。无论是对于个人开发者还是企业运维人员,掌握MySQL的备份方法都至关重要。本文将详细介绍MySQL的备份机制,包括逻辑备份、物理备份以及基于二进制日志的恢复方法。一、逻辑备份逻辑备份主要备份的是数据库的逻辑组件,如表、视图、存储过程等,通过SQL语句的形式进行保存。这种备份方式适用于中小型数据库,备份文件通常包含CREATE DATABASE、CREATE TABLE和INSERT等SQL语句。全库备份使用mysqldump工具可以备份整个数据库。例如:mysqldump -u root -p --all-databases > all_databases.sql库级备份备份指定的数据库:mysqldump -u root -p --databases dbname1 dbname2 > databases_backup.sql表级备份备份指定的表:mysqldump -u root -p dbname tablename1 tablename2 > tables_backup.sql备份表结构只备份表结构而不包含数据:mysqldump -u root -p --no-data dbname tablename > table_structure.sql恢复数据恢复数据可以通过mysql命令将备份文件导入到数据库中:mysql -u root -p dbname < backup.sql二、物理备份物理备份直接复制数据库的物理文件,如数据文件、日志文件等。这种备份方式适用于大型数据库,恢复速度较快,但操作相对复杂。全量备份全量备份是复制数据库的所有文件。可以使用Percona XtraBackup等工具进行热备份,无需关闭数据库服务。innobackupex --user=root --password='yourpassword' /path/to/backup增量备份增量备份只备份自上次备份以来发生变化的数据。MySQL的增量备份依赖于二进制日志(binlog)。差异备份差异备份备份自上次全量备份以来发生变化的所有数据。三、基于二进制日志的恢复二进制日志记录了所有对数据库进行修改的操作,可以用于数据恢复和主从复制。开启binlog在MySQL的配置文件my.cnf中添加以下配置:[mysqld] log-bin=mysql-bin server-id=1 查看二进制日志使用mysqlbinlog工具查看二进制日志内容:mysqlbinlog /path/to/mysql-bin.000001恢复数据根据二进制日志恢复数据,可以使用mysqlbinlog工具将日志内容应用到数据库中:mysqlbinlog --start-position=796 --stop-position=961 /path/to/mysql-bin.000001 | mysql -u root -p四、备份策略制定合适的备份策略对于确保数据安全至关重要。备份策略应考虑备份的频率、备份的类型(全量、增量、差异)、备份的存储位置以及备份的验证和恢复测试。定期备份根据业务需求和数据变化频率,制定定期备份计划,如每天全量备份,每小时增量备份。备份存储将备份文件存储在安全的位置,如远程服务器或云存储,以防止本地灾难导致数据丢失。备份验证定期对备份文件进行验证,确保备份文件可用且数据完整。恢复测试定期进行恢复测试,验证备份文件的恢复能力和恢复速度。五、总结MySQL的备份机制是确保数据安全的重要手段。通过逻辑备份和物理备份相结合的方式,可以实现对数据库的全面保护。同时,利用二进制日志进行增量恢复,可以进一步提高数据恢复的效率和准确性。制定合适的备份策略,定期进行备份和恢复测试,是确保数据库安全性的关键。希望本文能帮助读者深入理解Linux系统中MySQL的备份机制,并在实际工作中加以应用。
总条数:186 到第
上滑加载中