• [技术干货] 比较 EF Core & EF6
    EF CoreEntity Framework Core (EF Core) 是适用于 .NET 的新式对象数据库映射器。 它支持 LINQ 查询、更改跟踪、更新和架构迁移。EF Core 通过数据库提供程序插件模型与 SQL Server/Azure SQL 数据库、SQLite、Azure Cosmos DB、MySQL、PostgreSQL 和更多数据库配合使用。EF6Entity Framework 6 (EF6) 是专为 .NET Framework 设计的对象关系映射器,但支持 .NET Core。 EF6 是一款受支持的稳定产品,但我们不再对其进行积极开发。功能比较EF Core 提供了不会在 EF6 中实现的新功能。 但是,并非所有 EF6 功能都已在 EF Core 中实现。下表比较了 EF Core 和 EF6 中可用的功能。 这只是大致比较,没有列出全部功能,也未解释不同 EF 版本中相同功能之间的差异。EF Core 列指出了功能首次出现的产品版本。创建模型功能EF6.4EF Core基本类映射是1.0带有参数的构造函数2.1属性值转换2.1没有键的映射类型2.1约定是1.0自定义约定是1.0(部分;#214)数据注释是1.0Fluent API是1.0继承:每个层次结构一张表 (TPH)是1.0继承:每个类型一张表 (TPT)是5.0继承:每个具体类一张表 (TPC)是积压工作 (#3170)阴影状态属性1.0备用键1.0多对多导航是5.0多对多,无联接实体是5.0密钥生成:数据库是1.0密钥生成:客户端1.0复杂/已拥有类型是2.0空间数据是2.2模型格式:代码是1.0从数据库创建模型:命令行是1.0从数据库更新模型部分积压工作 (#831)全局查询筛选器2.0表拆分是2.0实体拆分是积压工作 (#620)数据库标量函数映射差2.0数据库表值函数映射差5.0字段映射1.1可为空引用类型 (C# 8.0)3.0模型的图形可视化效果是未计划支持 (1)图形模型编辑器是未计划支持 (1)模型格式:EDMX (XML)是未计划支持 (1)从数据库创建模型:VS 向导是未计划支持 (1)正在查询数据功能EF6.4EF CoreLINQ 查询是1.0可读内容生成的 SQL差1.0GroupBy 转换是2.1加载相关数据:预先加载是1.0加载相关数据:预先加载派生类型2.1加载相关数据:延迟加载是2.1加载相关数据:显式加载是1.1原始 SQL 查询:实体类型是1.0原生 SQL 查询:无键实体类型是2.1原始 SQL 查询:使用 LINQ 编写1.0显式编译的查询差2.0await foreach (C# 8.0)3.0基于文本的查询语言(实体 SQL)是未计划支持 (1)保存数据功能EF6.4EF Core更改跟踪:快照是1.0更改追踪:通知是1.0更改跟踪:代理是5.0访问跟踪的状态是1.0开放式并发是1.0事务是1.0批处理语句1.0存储过程映射是积压工作 (#245)断开连接低级别 API 图形差1.0断开连接端到端图形1.0(部分;#5536)其他功能功能EF6.4EF Core迁移是1.0数据库创建/删除 API是1.0种子数据是2.1连接复原是1.1拦截器是3.0事件是3.0(部分;#626)简单的日志记录 (Database.Log)是5.0DbContext 池2.0数据库提供程序 (2)功能EF6.4EF CoreSQL Server是1.0MySQL是1.0PostgreSQL是1.0Oracle是1.0SQLite是1.0SQL Server Compact是1.0 (3)DB2是1.0Firebird是2.0Jet (Microsoft Access)2.0 (3)Azure Cosmos DB3.0内存中(用于测试)1.01 EF Core 中不会实现某些 EF6 功能。 这些功能依赖于 EF6 的基础实体数据模型 (EDM),并且/或者是复杂功能,投资回报率相对较低。 欢迎提出反馈,但是,尽管 EF Core 支持许多在 EF6 中无法实现的功能,反过来,EF Core 支持 EF6 的所有功能却并不可行。2 更新到新的 EF Core 主版本时,第三方实现的 EF Core 数据库提供程序可能会延迟。 有关详细信息,请参阅数据库提供程序。3 SQL Server Compact 和 Jet 提供程序仅适用于 .NET Framework(而不适用于 .NET Core)。受支持的平台EF Core 3.1 通过使用 .NET Standard 2.0 在 .NET Core 和 .NET Framework 上运行。 但是,EF Core 5.0 确实可以在 .NET Framework 上运行。 有关更多详细信息,请参阅平台。EF6.4 通过多目标在 .NET Core 和 .NET Framework 上运行。针对新应用程序的选择指南除非应用需要仅在 .NET Framework 上受支持的内容,否则对于所有新应用程序都在 .NET Core 上使用 EF Core。针对现有 EF6 应用程序的选择指南EF Core 不是 EF6 的直接替换项。 从 EF6 迁移到 EF Core 可能需要更改应用程序。将 EF6 应用迁移到 .NET Core 时:如果数据访问代码稳定且不太可能开发或需要新功能,请继续使用 EF6。如果数据访问代码不断演变,或应用需要仅在 EF Core 中提供的新功能,请迁移到 EF Core。迁移到 EF Core 通常也是为了提高性能。 但是,并非所有方案都可提高性能,因此请先进行分析。有关详细信息,请参阅从 EF6 到 EF Core 的迁移。
  • [其他] GaussDB(DWS) 运维高频SQL语句汇总
    1. 查看长时间运行的SQL语句SELECT sysdate - query_start AS runtime, usename, coorname, pid, query_id, waiting, enqueue, substr(query, 1, 70) AS query FROM pgxc_stat_activity WHERE STATE != 'idle' AND usename != 'omm' AND usename != 'Ruby' ORDER BY runtime DESC LIMIT 50;2. 统计CN节点上的会话数SELECT enqueue, state,count(*) FROM pgxc_stat_activity GROUP BY 1,2;SELECT coorname,enqueue, state,count(*) FROM pgxc_stat_activity GROUP BY 1,2,3;SELECT usename,coorname,enqueue, state,count(*) FROM pgxc_stat_activity GROUP BY 1,2,3,4;3. 等待视图统计查询select wait_status, wait_event,count(*) from pgxc_thread_wait_status group by 1,2 order by 3 desc;4. 通过PID查杀语句EXECUTE DIRECT ON (CN_5003) 'SELECT PG_TERMINATE_BACKEND(281378607331584)';5. 查看占用内存大的SQLselect sessid, pg_size_pretty(sum_total) as total,pg_size_pretty(sum_free) free,pg_size_pretty(sum_used) used,query_id,query_start,state,waiting,enqueue,substr(query, 1,60) as query from (select sessid,sum(totalsize) as sum_total,sum(freesize) as sum_free,sum(usedsize) as sum_used from pv_session_memory_detail group by sessid ) a,pg_stat_activity b where split_part ( a.sessid,'.' , 2 ) = b.pid order by sum_total desc limit 10;6.  通过query_id查看SQL内存上下文占用情况select sessid, contextname, level,parent, pg_size_pretty(totalsize) as total ,pg_size_pretty(freesize) as freesize, pg_size_pretty(usedsize) as usedsize, datname,query_id, substr(query, 1,60) as query from pv_session_memory_detail a , pg_stat_activity b where split_part(a.sessid,'.',2) = b.pid  and query_id = '74309393851630636' order by totalsize desc limit 10; 
  • [干货汇总] 【大数据系列】不care工具,在大数据平台中Hive能自动处理SQL
    本文分享自华为云社区《[Hive执行原理](https://bbs.huaweicloud.com/blogs/348195?utm_source=csdn&utm_medium=bbs-ex&utm_campaign=other&utm_content=content)》,作者: JavaEdge 。 MapReduce简化了大数据编程的难度,使得大数据计算不再是高不可攀的技术圣殿,普通工程师也能使用MapReduce开发大数据程序。但是对于经常需要进行大数据计算的人,比如从事研究商业智能(BI)的数据分析师来说,他们通常使用SQL进行大数据分析和统计,MapReduce编程还是有一定的门槛。而且如果每次统计和分析都开发相应的MapReduce程序,成本也确实太高了。 有没有更简单的办法,可以直接将SQL运行在大数据平台? 先看如何用MapReduce实现SQL数据分析。 # MapReduce实现SQL的原理 常见的一条SQL分析语句,MapReduce如何编程实现? ```mysql ` SELECT pageid, age, count(1) FROM pv_users GROUP BY pageid, age;` ``` 统计分析语句,统计不同年龄用户访问不同网页的兴趣偏好,具体数据输入和执行结果: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/22/1650609311443266186.png) - 左边,要分析的数据表 - 右边,分析结果 把左表相同的行求和,即得右表,类似WordCount计算。该SQL的MapReduce的计算过程,按MapReduce编程模型 - map函数的输入K和V,主要看V V就是左表中每行的数据,如1, 25> - map函数的输出就是以输入的V作为K,V统一设为1 比如1, 25>, 1> map函数的输出经shuffle后,相同的K及其对应的V被放在一起组成一个,作为输入交给reduce函数处理。比如2, 25>, 1>被map函数输出两次,那么到了reduce这里,就变成输入2, 25>, 1, 1>>,这里的K是2, 25>,V集合是1, 1>。 在reduce函数内部,V集合里所有的数字被相加,然后输出。所以reduce的输出就是2, 25>, 2> ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/22/1650609380761298262.png) 如此,一条SQL就被MapReduce计算好了。 在数据仓库中,SQL是最常用的分析工具,既然一条SQL可以通过MapReduce程序实现,那有无工具能自动将SQL生成MapReduce代码?这样数据分析师只要输入SQL,即可自动生成MapReduce可执行的代码,然后提交Hadoop执行。这就是Hadoop大数据仓库Hive。 # Hive架构 Hive能直接处理我们输入的SQL(Hive SQL语法和数据库标准SQL略不同),调用MapReduce计算框架完成数据分析操作。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/22/1650609395656925319.png) 通过Hive Client(Hive的命令行工具,JDBC等)向Hive提交SQL命令: - 若为DDL,Hive会通过执行引擎Driver将数据表的信息记录在Metastore元数据组件,该组件通常用一个关系数据库实现,记录表名、字段名、字段类型、关联HDFS文件路径等这些数据库的元信息 - 若为DQL,Driver就会将该语句提交给自己的编译器Compiler进行语法分析、语法解析、语法优化等一系列操作,最后生成一个MapReduce执行计划。然后根据执行计划生成一个MapReduce的作业,提交给Hadoop MapReduce计算框架处理。 对一个简单的SQL命令: ```mysql SELECT * FROM status_updates WHERE status LIKE ‘michael jackson’; ``` 其对应的Hive执行计划: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/22/1650609437583417627.png) Hive内部预置了很多函数,Hive执行计划就是根据SQL语句生成这些函数的DAG(有向无环图),然后封装进MapReduce的map、reduce函数。该案例中的map函数调用了三个Hive内置函数TableScanOperator、FilterOperator、FileOutputOperator,就完成了map计算,而且无需reduce函数。 # Hive如何实现join操作 除了简单的聚合(group by)、过滤(where),Hive还能执行连接(join on)操作。 pv_users表的数据在实际中无法直接得到,因为pageid数据来自用户访问日志,每个用户进行一次页面浏览,就会生成一条访问记录,保存在page_view表中。而age年龄信息则记录在用户表user。 ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/22/1650609484669408457.png) 这两张表都有一个相同的字段userid,据该字段可连接两张表,生成前面例子的pv_users表: ```mysql SELECT pv.pageid, u.age FROM page_view pv JOIN user u ON (pv.userid = u.userid); ``` 该SQL命令也能转化为MapReduce计算,连接过程如下: ![image.png](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20224/22/1650609508775654849.png) join的MapReduce计算过程和前面的group by稍有不同,因为join涉及两张表,来自两个文件(夹),所以需要在map输出的时候进行标记,比如来自第一张表的输出Value就记录为1, X>,这里的1表示数据来自第一张表。这样经过shuffle以后,相同的Key被输入到同一个reduce函数,就可以根据表的标记对Value数据求笛卡尔积,用第一张表的每条记录和第二张表的每条记录连接,输出就是join的结果。 所以打开Hive源码,看join相关代码,会看到一个两层for循环,对来自两张表的记录进行连接操作。 # 总结 开发无需经常编写MapReduce程序,因为网站最主要的大数据处理就是SQL分析,因此Hive在大数据应用很重要。 随Hive普及,我们对在Hadoop上执行SQL的需求越强,对大数据SQL的应用场景也多样化起来,于是又开发了各种大数据SQL引擎。 Cloudera开发了Impala,运行在HDFS上的MPP架构的SQL引擎。和MapReduce启动Map和Reduce两种执行进程,将计算过程分成两个阶段进行计算不同,Impala在所有DataNode服务器上部署相同的Impalad进程,多个Impalad进程相互协作,共同完成SQL计算。在一些统计场景中,Impala可做到ms级计算速度。 后来Spark诞生,也推出自己的SQL引擎Shark,即Spark SQL,将SQL语句解析成Spark的执行计划,在Spark上执行。由于Spark比MapReduce快很多,Spark SQL也相应比Hive快很多,并且随着Spark的普及,Spark SQL也逐渐被人们接受。后来Hive推出了Hive on Spark,将Hive的执行计划转换成Spark的计算模型。 我们还希望在NoSQL执行SQL,毕竟SQL发展几十年,积累庞大用户,很多人习惯用SQL解决问题。于是Saleforce推出了Phoenix,一个执行在HBase上的SQL引擎。 这些SQL引擎只支持类SQL语法,并不能像数据库那样支持标准SQL,特别是数据仓库领域几乎必然会用到嵌套查询SQL:在where条件里面嵌套select子查询,但几乎所有的大数据SQL引擎都不支持。然而习惯于传统数据库的使用者希望大数据也能支持标准SQL。 回到Hive。Hive本身的技术架构其实并没有什么创新,数据库相关的技术和架构已经非常成熟,只要将这些技术架构应用到MapReduce上就得到了Hadoop大数据仓库Hive。但是想到将两种技术嫁接到一起,却是极具创新性的,通过嫁接产生出的Hive极大降低大数据的应用门槛,也使Hadoop得到普及。 >参考 - https://learning.oreilly.com/library/view/hadoop-the-definitive/9781491901687/ch17.html#TheMetastore
  • [互动交流] FI产品 使用idea本地调式spark sql 如何配置
    【功能模块】【操作步骤&问题现象】1、我在本机idea上 执行sparksql 查询hive库的数据 报错2、已经hive的相关配置文件放在resources下、 jar包也是从集群上的spark下的lib下导出来的,请问还需要配置说明东西  谢谢【截图信息】【日志信息】(可选,上传日志内容或者附件)
  • [技术干货] 数据库的迁移
    所谓数据库迁移就是一个数据库到另一个数据库之间的任意形式的数据移动。本文从热迁移和冷迁移的概念以及基本迁移流程简单分享一下:一、数据库迁移主要分为热迁移和冷迁移:1、热迁移是将内存数据和硬盘数据同步进行迁移。热迁移的优势在于其对用户业务的影响是非常小的;热迁移对内存数据进行了迁移,用户业务应用对其是无感知的。而缺点是热迁移的过程是不可中断的,整个操作过程相对复杂。2、冷迁移就是在关机迁移。优势是整个冷迁移过程的操作简单,一般为自动化操作。但其缺点是该方式不支持内存数据的保存,容易导致内存数据的丢失。二、数据库迁移关键流程数据库迁移的工程按照进度可以划分为前期规划、中期实施和后期运维3个阶段,具体可以分为源数据库及应用系统调研、兼容性和风险评估、可行性验证、全面业务改造、全面业务测试、割接演练、迁移执行、业务验证、正式割接和护航保障10个关键环节,如下图1、源数据库及应用系统调研:源数据库及应用系统调研有助于后续深入评估改造点和工作量,有利于定位系统迁移过程中的难点和风险,其调研内容可以分为源数据库、应用系统、数据库和应用系统3个方面。 (1)源数据库调研:需要考虑数据库结构、数据类型、数据库性能、数据使用场景4部分基础数据。数据库结构和数据类型是静态数据,可以通过语法、语义比对完成调研;数据库性能和数据使用场景是动态数据,与其对应的业务属性、数据库硬件资源、数据库自有能力、数据属性和应用系统属性直接相关。 (2)应用系统调研:主要是发现应用和数据库之间的调用关系和调用方式,厘清应用各个模块与数据库调用SQL的兼容特点,明确应用在各个模块转换的改造点。通过调用SQL详情实现改造点定位,即交互SQL点定位。 (3)数据库与应用系统调研:数据库与应用系统的关联关系通常包含但不限于数据复制链路、API结构调用等内容,其架构关系的梳理是迁移流程的重中之重,需要投入大量人力物力。掌握源数据库和应用的结构、架构、性能、关系拓扑,有助于后续决策。2、兼容性和风险评估:调研完成后,进入兼容性和风险评估环节。兼容性评估工作宜从结构语法分析、结构语义分析、上下文环境兼容分析几方面进行;风险评估工作主要包括目标库性能风险、数据一致性风险、应用改造风险、时间窗口风险和上线误操作风险五大方面。3、可行性验证:充分调研和评估后,迁移工程进入到可行性验证环节,即POC测试。其流程可划分为4个阶段:其一,选取业务中典型的交易模块,制定POC测试内容;其二,准备、部署POC测试环境;其三,根据POC预设,完成测试需求;其四,POC测试总结。针对数据库的特性,在可行性验证过程中需重点关注几个方面:其一,异常场景下事务是否一致;其二,异常场景下副本是否一致;其三,异常场景下大批量已提交事务回滚是否对系统有影响;其四,锁冲突较多的场景下是否对系统有影响;其五,副本数据的时延是否满足系统要求。验证结束后,需出具可行性验证报告,说明应用系统迁移至数据库是否可行,以及相关注意事项,为后续迁移工作打好基础。4、全面业务改造:改造工作繁琐,需要对业务逻辑、应用程序、源和目标数据库相关语法规则进行深入了解,为保证改造有效进行,宜遵循3个原则:其一,业务改造过程中需要谨慎地规划以及选取良好的方法,结合数据库产品自身技术特点,进行一系列数据库及应用程序的调整;其二,业务改造宜遵循从宏观到微观、从整体到局部、自顶向下的方式;其三,宜遵循先实现再调优的原则,性能调优需根据实际软硬件环境和业务场景,一次或者多次调整。业务改造可以从几个方面依次进行:首先是数据类型,目标数据类型范围和精度应不小于源数据类型,以确保业务数据不会丢失,且目标数据类型范围和精度应避免超大于源数据类型,以免带来性能下降。其次是函数,改造场景可能会遇到函数同名,但在源数据库和目标数据库功能不同或不完全相同;函数同名,但参数隐式转换规则不同;函数同名,但参数个数或者参数类型不同;函数不同名,但功能相同;无对应函数,需通过其他方式实现。最后是语法规则,除了应当遵循ANSI或ISO的SQL标准语法,数据库方言的使用难以避免,因此需要将源数据库自身支持的语法规则调整为目标数据库的语法规则。5、全面业务测试:测试环节是迁移关键环节的重中之重,需要投入大量的时间和资源,稍有不慎,可能会导致后续的迁移失败、数据丢失甚至是业务中断、混乱的灾难性后果。全面业务测试通常包含功能测试、性能测试、稳定性测试、可靠性测试、扩展能力测试、安全能力测试、回退方案验证等。测试环节的典型测试类型及测试项如下:6、割接演练:割接演练是针对正式迁移前,模拟真实上线环境下,对系统进行的压力测试和破坏性测试,主要分为割接方案制定、压力测试和破坏性测试、测试总结、新旧系统同步互备和切换演练5部分。割接方案中应包含系统备份方案、应急预案、回退方案,明确割接的操作步骤、操作时间和操作人员,对新系统实施压力测试和破坏性测试,模拟在最极端环境下新系统功能的完整性、稳定性和高可靠性。正式割接前的备份工作必不可少,在新环境上线前务必做好旧程序包的保留和数据同步,以便在紧急情况可以快速回退。切换演练需制定切换检查清单,演练期间严密监控容灾数据库的系统负载、异常等待事件等内容。7、迁移执行:迁移执行宜按照最少改动的数据库结构和应用系统SQL代码;完整、准确的数据对象及数据迁移;最短的业务中断的原则进行,其包含的流程如图迁移环境检测包含主机环境检测、网络环境检测和数据库环境检测。结构迁移是指将源数据库的建表语句迁移到目标端不同数据库中,迁移完成保证源、目标数据库中的建表语句功能、性能等价使用。数据迁移分为全量数据迁移和增量数据迁移。迁移结束环境确认需要重建序列、启用触发器和收集执行计划等。构建数据回流是为保证业务迁移后目标数据库切换为生产库出现故障无法持续对外提供业务时,保证目标端已经变化的数据能够迁移回流到原来的生产库,并保证业务不中断。 8、业务验证:业务验证分为迁移数据验证和业务功能验证。从源数据库导入到目标数据库中的历史数据文件可以按主键顺序进行组织,以文本文件的方式卸载迁移数据,并确保导出数据能够按照主键有序输出。对导入文件和导出文件分别进行比较操作,通过比对结果是否一致,完成迁移数据的一致性验证。业务功能验证分为运行过程比对、运行结果比对和静态数据比对。 (1)运行过程比对:通过在原和新应用系统前端增加网络镜像分流设备,将发往原应用系统的网络数据镜像分流到新应用系统中,使用覆盖实际交易场景的大量生产数据进行连续测试。在运行过程中,解析目标、源数据库中的日志文件,根据流水号、主键、时间等唯一性标识,比对日志文件中新旧值的变化,找出异常过程,达到验证目标系统数据正确性与一致性目的。 (2)运行结果比对:在原应用系统和新应用系统前端增加网络镜像分流设备,将发往原应用系统的网络数据镜像分流到新应用系统中,将目标、源数据库返回的结果信息保存到文件或数据库中,根据流水号、主键、时间等唯一性标识,比对目标、源数据库的交易结果。(3)静态数据比对:根据源数据库的每日备份时间,在目标数据库做相同时刻的备份操作,备份完成后,将两份备份文件导入到比对库中,按表逐条比对两份数据一致性以及每张表的数据总量,验证目标系统数据的正确性与一致性。9、正式割接:割接前通常需要至少3次割接演练,以确保割接过程中各个环节没有疏漏,并根据不同业务系统情况制定割接流程,分配每个流程责任人,通关制完成各个环节。正式割接环节分为生产环境准备和按照割接方案正式执行割接两部分。 10、护航保障: 迁移完成后,最危险的环节是切换后生产环境的第一个业务高峰,需要配置专业的数据库专家,快速响应应用和数据库出现的突发问题。之后,需要定期跟踪一定时间,以保障业务系统的稳定运行。最终的护航时间,需要根据实际情况确定。如果遇到突发情况,在无法处理的情况下,应依据回退方案和演练细则逐步完成回退。欢迎补充~
  • [技术干货] GaussDB(DWS) GUC参数修改、查看[转载]
    背景GaussDB(DWS)提供了多种修改GUC参数的途径,用户可以通过sql、界面、shell工具等多种形式对guc参数进行调优、修改。用户面修改GUC参数从用户面修改,打开华为云->数据仓库服务->点开集群名称,可以看到有个参数修改菜单,目前GaussDB(DWS)大部分版本都在这里提供了部分参数的修改能力这里以修改时区为例,在页面上过滤到时区字段,改成北京东八区,然后提交然后集群会有一个配置中的异步任务然后我们用sql查看一下当前时间,已经生效了注意:如果修改了需要重启才能生效的参数,必须在页面点击重启集群,否则参数不会生效使用SQL修改GUC参数具体可以参照帮助文档 https://support.huaweicloud.com/devg-dws/dws_04_0885.html设置数据库级别的参数,在下次会话中生效。ALTER DATABASE postgres SET timezone TO "UTC";设置用户级别的参数,在下次会话中生效ALTER USER Ruby SET timezone TO "UTC";设置会话级别的参数,立即生效,退出登录失效SET timezone TO "UTC";不论是哪种方式设置的参数,都可以使用【show+参数名】查看,查看所有参数可以使用show all;注意修改GUC参数应该是个谨慎的行为,修改错误将有可能导致集群不可用如果有些参数用sql修改报错,可以在页面上操作
  • [分享驿站] 某项目组培训学习规划(含HCIP课件)
    适合阶段培训主题培训简介学习材料学习时间萌新GaussDB(DWS)产品介绍本讲是第一场,聚焦介绍GaussDB(DWS)应用场景、关键特性与案例介绍、典型配置,让您初步了解GaussDB(DWS)是啥,有啥特性,有哪些成功案例等。https://bbs.huaweicloud.com/videos/103289Week 1,Day 1图解数据仓库服务,图文并茂,更生动直观https://support.huaweicloud.com/productdesc-dws/dws_01_1110.html基础GaussDB(DWS) 数据迁移本讲主要讲述通过GDS和COPY工具进行物理数据的迁移,通过gs_dump/gs_resotre迁移元   数据,以及介绍GaussDB(DWS)的ETL工具,对Migration工具的使用简单说明。 https://bbs.huaweicloud.com/videos/103291Day 2-3GaussDB(DWS) 数据库对象设计本讲从GaussDB(DWS)   数据库整体设计,对象命名规范,对象设计原则,Sql编写规则四个方面详细讲解了应用层如何用好数据仓库GaussDB(DWS) https://bbs.huaweicloud.com/videos/103292Day 4-5进阶GaussDB(DWS) SQL进阶及应用开发指南本讲分两部分,第一部分Sql进阶,详细讲解了GaussDB(DWS)的数据字典,数据类型,函数操作符,存储过程等,第二部分应用程序应用指南,从数据库驱动概念,基于ODBC/JDBC的应用程序开发。https://bbs.huaweicloud.com/videos/103295Week2 Day 1-3罗列了众多的第三方应用于GaussDB(DWS)的对接方法https://bbs.huaweicloud.com/forum/forum.php?mod=forumdisplay&orderby=lastpost&fid=598&filter=typeid&typeid=1927GaussDB(DWS)事务、锁机制管理本讲为您介绍华为云数仓GaussDB(DWS)   单机事务机制,分布式事务机制,锁机制,并介绍一般的锁问题定位防范,例如死锁问题。https://bbs.huaweicloud.com/videos/103294Day 4-5运筹帷幄-GaussDB(DWS)教你分析阻塞SQL的几个妙招https://bbs.huaweicloud.com/forum/thread-169553-1-1.htmlGaussDB(DWS)性能调优本讲为您介绍华为云数仓GaussDB(DWS)   调优的基本理论、常见的SQL性能问题的定位手段和解决方案 https://bbs.huaweicloud.com/videos/103296Week3不可不知的调优技巧-GaussDB(DWS)表结构优化https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=167614【干货博文合集】数仓性能调优必读,带你进阶为性能调优高手https://bbs.huaweicloud.com/forum/thread-107669-1-1.html高阶GaussDB(DWS)资源负载管理本讲为您介绍华为云数仓GaussDB(DWS)   多租户机制,资源管理及负载管理机制,让您了解多租户的基本概念及基本设置方法,了解资源负载的基本原理及并发管理机制,初步进行资源负载分析和配置https://bbs.huaweicloud.com/videos/103295Week 4, Day 1-2打造企业数据“高内聚,低耦合”--试试GaussDB(DWS)逻辑集群,实现数据物理隔离https://bbs.huaweicloud.com/forum/thread-167616-1-1.htmlGaussDB(DWS)安全与权限设计本讲围绕华为云数仓GaussDB(DWS)   数据安全的核心问题:谁能看?能看啥?看没看?依托分布式架构,逐层为您解答,透明加密,数据加密,三权分立,行列及控制,用户管理,私有用户等概念 https://bbs.huaweicloud.com/videos/103297Day 3-5GaussDB(DWS)数据落盘安全吗?来直面三大灵魂拷问https://bbs.huaweicloud.com/forum/thread-133505-1-1.html大数据时代的隐私利器-GaussDB(DWS)数据脱敏https://bbs.huaweicloud.com/forum/forum.php?mod=viewthread&tid=141229
  • [其他] GaussDB(DWS) 使用Data Studio工具查询语句返回结果时间长
    问题现象:1. 使用Data Studio客户端工具执行简单的SELECT SQL查询时,发现返回结果的时间长,需要3分钟。2. 在语句前增加explain performance后执行SQL查询,执行时间正常,在几百毫秒内返回结果。问题分析:打开日志记录语句的参数:set log_statement='all';在Data Studio里执行SQL语句时,观察CN的日志输出,找到以下语句:[BACKEND] LOG: execute <unnamed>: select s.nspname schema_name, o.object_name table_name, a.attname colu mn_name, d.description from pg_catalog.all_objects o, pg_catalog.pg_namespace s, pg_catalog.pg_attribute a, pg_catalog.pg_description d where o.namespace = s.oid and o.object_id = a.attreli d and o.object_id = d.objoid and d.objsubid = a.attnum and object_type in ('table','view') and (s.nspname, o.object_name, a.attname) in (($1,$2,$3),($4,$5,$6),($7,$8,$9),($10,$11,$12),($13, $14,$15))这个语句是Data Studio发送的用于获取列的信息,该语句执行时间较长。解决方案:升级Data Studio版本,已解决系统表语句执行时间长的问题。下载更新版本:在https://support.huawei.com/里搜索下载 GaussDB Tools 8.0.2.SPC070
  • [技术干货] 自治数据库是什么 ?
    自治数据库的定义自治数据库是一种采用了机器学习技术,可自动执行数据库调优、保护、备份和更新以及其他传统上由 DBA 执行的常规管理任务的云数据库,与传统数据库不同,它无需人工干预就能执行所有这些以及更多其他任务。为什么要使用自治数据库?数据库是一种存储重要业务信息的 IT 设备,对现代企业高效运营至关重要。然而在现实中,数据库管理员 (DBA) 常常需要耗费大量时间和精力来手动管理和维护数据库,非常容易出错,给数据库正常运行时间、性能和安全性带来灾难性影响。例如,未及时、正确地打补丁和安装安全更新可能导致数据库漏洞,削弱甚至造成数据库保护措施完全失效,进而使企业面临严重的数据泄露风险,遭受严重的财务影响和商誉损失。此外,随着业务应用不断将新记录添加到现有数据库,使用数据库信息创建报告、分析趋势和探测异常,数据库会迅速增长到 TB 级规模,变得高度复杂,导致 DBA 难以有效进行管理、保护和调优,发挥数据库的最佳性能。而一旦数据库运行缓慢或不可用,员工生产力就将受到影响,客户也会感到沮丧和失望。面对加速增长的数据规模,企业需要高效、安全地管理数据库,增强数据安全性,降低停机时间,提高数据库性能和消除人为错误。而选择自治数据库,您可以轻松做到这一切。数据库可存储的数据类型通常一个数据库管理系统既可以存储高度结构化的数据(例如会计记录或客户信息),也可以存储非结构化数据(例如数字图像或电子表格)。这些数据既支持客户和员工直接访问,也支持通过企业软件、网站或移动应用间接访问— 许多软件(例如商务智能、客户关系管理和供应链应用)都使用数据库中存储的数据。自治数据库的组成要素按照负载类型划分,自治数据库包含两个关键要素。数据仓库执行与商务智能活动相关的众多功能,并使用提前准备好的数据进行分析。此外,它还可以管理所有数据库生命周期操作,对数百万行数据执行查询扫描,可以灵活扩展以满足业务需求,并在短短数秒钟时间内完成部署。事务处理适用于基于时间的事务流程,例如实时分析、个性化和欺诈检测。它基于预定义操作运行,通常涉只涉及极少量的记录,还支持简易应用开发和部署。自治数据库的工作原理自治数据库充分利用 AI 和机器学习技术,支持全面、端到端的自动化供应、安全性、更新、可用性、性能、变更管理和防错。在这一意义上,自治数据库具有以下特征。自治驱动自治数据库可自动化管理、监视和调优所有数据库和基础设施。这意味着,DBA 可以专注于更加重要的任务,包括数据聚合、建模、处理、治理策略,以及帮助开发人员使用数据库内特性和功能,而尽可能减少对应用代码的更改。自治安全自治数据库内置专业的安全性功能,可有效防范外部攻击和内部恶意用户访问,避免因未打补丁或执行数据库加密而遭到网络攻击。自治修复自治数据库可防止包括计划外维护在内的停机。据统计,自治数据库每个月包括修补在内的停机时间不超过 2.5 分钟。自治数据库的优势自治数据库可提供以下多种优势:尽可能提高数据库正常运行时间、性能和安全性 — 包括自动修补和修复通过自动化技术消除易于出错的手动管理任务自动执行日常任务,降低成本,提高工作效率此外,自治数据库管理员还可以专注处理具有更高业务价值的的工作,例如数据建模,为程序员提供数据架构支持,以及规划未来容量等。企业则可以缩减 DBA 团队,或抽调 DBA 去从事更具战略性的任务,从而节省成本和资金。智能技术驱动自治数据库智能技术可驱动自治数据库自动化处理各种虽繁琐但又极其重要的任务,例如日常维护、扩展、安全性和数据库调优。例如,利用机器学习和人工智能算法,您可以优化查询,自动管理内存和存储,打造一个完全自调优的数据库。在自治数据库中,机器学习算法可以分析大量数据记录,标记异常值和异常模式,帮助企业提高安全性,防范入侵者破坏,还可以在系统运行时自动、连续、无人工干预地执行修补、调优、备份和升级操作,尽可能减少人为错误或恶意行为,确保数据库高效运行、安全无失。此外,自治数据库还具有以下特性:易于扩展基于云的数据库服务器可以按需即时伸缩计算和内存资源。例如,企业可以在每个季度末将计算核心从 8 个扩展到 16 个以满足峰值处理需求,然后在处理结束后将计算核心缩减到 8 个以降低成本。事实上,您甚至可以在周末关闭所有计算资源,然后在周一早上重新启动,进一步降低成本。无缝数据库修补在现实中,很多数据泄露都要归咎于未及时安装安全补丁和修补漏洞。对此,自治数据库可以自动按顺序滚动安装云服务器补丁,有效解决这一问题,避免业务停摆。集成式智能自治数据库集成了基于机器学习和人工智能的监视、管理和分析功能,可以自动化执行调优操作,防止应用中断,增强整个数据库应用的安全性。自治数据库赋能开发人员自治数据库能够提供一个预配置、全托管、高度安全的环境,基于其中的数据,开发人员可以快速构建安全、可扩展的企业应用。如何选择自治数据库?自治数据库可提供多种优势。在选择自治数据库产品时,请关注以下关键特性。自动供应自动部署容错、高度可用的任务关键型数据库,同时无缝扩展数据库,提供服务器故障保护,在应用运行过程中以滚动方式应用更新。自动配置自动配置数据库,针对特定负载进行优化。全面优化内存配置、数据格式和访问结构的一切要素,提高性能。您只需加载数据即可开始使用。自动索引自动监视负载并检测缺失索引,加快应用运行。在实施之前验证每一个索引,确保其有效,同时使用机器学习从其自身错误中学习。自动伸缩根据负载需求自动扩展计算资源;所有扩展均可在应用运行过程中在线上完成;支持真正的按用量付费。自动数据保护通过统一的管理控制台自动保护数据库中的敏感数据和规范数据;评估配置、用户、敏感数据和异常数据库活动的安全性。自动化安全自动对整个数据库、备份以及所有网络连接进行加密;无需访问操作系统或管理员特权即可阻止网络钓鱼攻击;有效防范云操作和所有内部恶意用户访问。自动备份自动每日或按需备份数据库;可将数据库还原或恢复到您指定的过去 60 天内的任意时间点。自动打补丁自动零停机修补或升级。修补操作将在集群节点或服务器之间循环进行,同时应用将保持不间断运行。自动化问题检测和解决通过模式识别自动预测硬件故障,避免长时间暂停。IO 会立即重定向,绕开非正常运行的设备,从而避免数据库挂起。持续监视各个数据库,针对任意偏差自动生成服务请求。自动故障切换自动化故障切换至备用数据库,零数据丢失;对最终用户应用完全透明;SLA 高达 99.995%。自治数据库的未来在今天,数据的生成速度已经远远超过了手动数据管理和处理的速度,在高效、安全地捕获关键业务洞察方面,现代企业面临着严峻的挑战。而得益于智能自动化特性,自治数据库可提供众多传统数据库无法企及的优势。未来,越来越多的企业将迁移到自治数据库,通过自治数据库巩固和提高竞争优势,让 IT 部门专注于创新而不是数据库管理。
  • [技术干货] 2022年有哪些重要的数据库发展趋势?
    据Expert Market Research研究,2020年全球数据库管理系统(DBMS)市场估计接近631亿美元,预计到2026年将达到1256亿美元,在此期间的复合年增长率为12.4%。以下是推动数据库市场增长的主要趋势。过去的几年中创造的数据超过人类以往历史,有效地管理、操纵和保护这些信息资产的需求从未像现在这样重要,这一需求一直由领先的数据库供应商来解决,然而,在过去的十年中,无数的挑战者已经进入了这个战场,扰动着数据爆炸时代的数据库市场秩序。近年来,数据库经历了戏剧性地演变,一些类型的数据库已经走到了疲软道路上,而另一些则蓬勃发展到今天。资深的DBA会回忆起他们在早期的Informix、SQL server和Oracle DBMS产品上的切身体会(后两者仍然占主导地位),而千禧年的开发者则回忆起MySQL/LAMP栈和PostgreSQL的开源简单性。最后,值得一提的是,今天这一代的DevOps工程师更喜欢NoSQL数据库的非结构化敏捷性,如MongoDB和DynamoDB。今天的数据库目前,大多数数据库属于两类中的一类:关系型数据库管理系统(RDBMS)和较新的非结构化和/或特殊应用数据库。前者自20世纪70年代以来一直存在,由相关表格组成,而这些表格又是由行和列组成的。关系型数据库使用结构化查询语言(SQL)进行操作,这是执行创建、读取、更新、删除(CRUD)功能的事实标准语言。RDBMS是企业计算的主要数据库类型,其SQL语言是与数据库通信的通用语言。根据ScaleGrid.io最近的一项调查,基于SQL的RDBMS仍然占部署中的数据库的60.5%。事实上,SQL语言的持续流行导致了大数据产品的出现,比如被恰当地命名为SQL-on-Hadoop和Apache Hive的产品,都采用了这种语言。云计算的出现使数据处理能力得到了前所未有的横向扩展,正好可以支持互联网所带来的结构化和非结构化数据的飞速增长。随着后者日益突出,一些人认为需要一个新的数据库范式。因此,NoSQL应运而生,这是一个广泛的类别,除了那些使用SQL作为其主要语言的数据库,几乎包括所有的数据库。由于NoSQL数据库在模式或结构方面没有固定的要求,它们是当今利用DevOps工具集和CI/CD管道的软件环境的理想选择。数据库市场的五个趋势据Expert Market Research研究,2020年全球数据库管理系统(DBMS)市场估计接近631亿美元,预计到2026年将达到1256亿美元,在此期间的复合年增长率为12.4%。以下是推动数据库市场增长的主要趋势。1. SQL重回巅峰十年前,新加入的NoSQL似乎是长期占主导地位的基于SQL的DBMS的强有力挑战者。如今,人们或多或少承认,在可预见的未来,SQL仍将是DBMS的基石。即使是较新的基于机器学习的产品,如MindDB的ML框架和AWS Redshift ML,也已经将SQL作为默认的查询语言。2. ML驱动的数据库谈到ML,在数据生存的地方整合ML模型的上升趋势正在成为供应商的标准做法,企业方面的解决方案,如Oracle自主数据库和微软SQL Server机器学习服务,以及上述的MindsDB和SingleStore创业公司的产品。3. 微服务集成今天的现代软件工程团队使用微服务方法设计和构建应用程序。也就是说,他们将应用架构为一系列较小的、API驱动的服务,这提高了可扩展性和敏捷性,但对于那些拥有存储在传统单体数据库中的现有数据的组织来说,这可能是个问题。幸运的是,许多较新的数据库产品,最引人瞩目的NoSQL供应商,如MongoDB和AWS DynamoDB,提供了微服务所需的模式灵活性、冗余/可扩展性要求和无服务器架构模式支持。4. 内存数据库今天的关键任务软件解决方案需要最小的数据库延迟以获得最佳性能。不幸的是,传统的DBMS依靠迟缓的磁盘读写操作将数据存储到媒介(如硬盘驱动器、固态驱动器)。出于这个原因,内存数据库已经成为这些关键用例的有力替代方案:因为记录是直接从内存(RAM)中存储和检索的,所以可以实现更快和更可靠的性能。此外,流行的解决方案,如Redis,支持更多的数据结构类型和自定义访问模式,允许简化软件代码(注:不需要数据结构转换/序列化)。5. 更强大的数据库安全层随着网络攻击和数据泄露继续占据技术世界的头条,人们比以往任何时候都更关注软件应用程序的数据层安全。更多的供应商正在为他们的产品增加更强大的、内置的安全功能。例如,甲骨文公司现在在数据库层面集成了永远在线的加密和自动修补功能,而亚马逊RDS包括一个内置的防火墙(即安全组),用于基于规则的数据库访问。结论不管是什么类型的数据库,数据库都将继续作为现代互联网应用程序的关键基础设施,能够可靠和高效地处理和存储大量数据。当然,多年来,关于“大”的定义已经改变。一般来说,无法通过传统电子表格管理的数据集是DBMS的理想选择。随着对支持特定用途的数据库的需求不断增加,如时间序列和地理空间应用,你可以期待在不久的将来,从新的和传统的DBMS产品中看到大量迅速发展的特性。作者:Leon Yen 来源:https://www.51cto.com/article/705010.html
  • [其他] GaussDB(DWS) 创建分区表来提升SQL性能
    在GaussDB(DWS) 上执行查询时,经常会发现性能瓶颈点在表的扫描上, 查看磁盘IO使用情况,发现使用率经常达到100%。针对上述场景,结合SQL语句的业务场景,如果表的某一列有日期特征,在查询条件中也经常使用这个日期列过滤数据,那么我们就可以考虑将这个表建成分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储。这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。分区表和普通表相比具有以下优点:改善查询性能:对分区对象的查询可以仅搜索自己关心的分区,提高检索效率。增强可用性:如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。方便维护:如果分区表的某个分区出现故障,需要修复数据,只修复该分区即可。GaussDB(DWS)支持的分区表为范围分区表。范围分区表:将数据基于范围映射到每一个分区。这个范围是由创建分区表时指定的分区键决定的。分区键经常采用日期,例如将销售数据按照月份进行分区。(一)建分区表语句例子CREATE TABLE pt_table1(id INT, create_time TIMESTAMP, conent TEXT) WITH (orientation=column) DISTRIBUTE BY HASH (id) PARTITION BY RANGE (create_time) ( PARTITION P202203 start('2022-03-01'::timestamp) end('2022-04-01'::timestamp) every (interval '1 day') ) ENABLE ROW MOVEMENT;上面的这个语句按天建立了一个列存分区表,建立了一个月的分区,其中2022-03-01之前的数据保存在第一个分区里,3月的数据按天保存在每个分区里。(二)查看分区信息的语句select * from user_tab_partitions where schema = 'public' and table_name = 'pt_table1' order by high_value;(三)增加新分区ALTER TABLE pt_table1 ADD PARTITION P202204 START('2022-04-01'::timestamp) END('2022-05-01'::timestamp) EVERY(interval '1 day');(四)增加历史分区对历史数据增加分区,需要使用分区的SPLIT方法。ALTER TABLE pt_table1 SPLIT PARTITION P202203_0 into (PARTITION P202202 START('2022-02-01'::timestamp) END('2022-03-01'::timestamp) EVERY (interval '1 day'));(五)增加MAXVALUE分区将超过右边界的值都放入一个分区,可以使用MAXVALUE分区ALTER TABLE pt_table1 ADD PARTITION pmax END(MAXVALUE);(六)指定分区名查询分区的数据SELECT COUNT(*) FROM pt_table1 PARTITION (P202202_1);使用分区表后SQL的性能往往会带来数十倍到百倍的提升,并且磁盘的读IO会大幅下降,还有更多的表设计最佳实践,请参考以下链接:https://support.huaweicloud.com/bestpractice-dws/dws_05_0046.html
  • [分享驿站] GaussDB(DWS) SQL进阶培训相关问答
    培训资料:https://partner.huawei.com/university/webui_portal/#/cert/certDetails?certId=CRE201912180000 ## 1. 如何查看node_group和schema的权限 目前已有列,表,自定义对象,当前角色等视图可以查看权限,schema和group暂时未加入系统视图,需要自己写SQL查看,方法如下: grantor 授权人 grantee 权限持有人 public 所有用户 is_grantable 当前用户是否可以授权给其它人 ```SQL postgres=# select * from information_schema.column_privileges; --列级权限查询,privilege_type可看都有哪些权限 grantor | grantee | table_catalog | table_schema | table_name | column_name | privilege_type | is_grantable -----------+-----------+---------------+--------------------+---------------------------------------+-------------------------------------+----------------+-------------- user1 | PUBLIC | postgres | pg_catalog | pgxc_stat_replication | client_port | SELECT | NO user1 | user1 | postgres | pg_catalog | pg_authid | rolvaliduntil | INSERT | YES user1 | PUBLIC | postgres | pg_catalog | pg_statio_sys_indexes | idx_blks_hit | SELECT | NO postgres=# select * from information_schema.table_privileges; --表级权限查询,privilege_type可看都有哪些权限 grantor | grantee | table_catalog | table_schema | table_name | privilege_type | is_grantable | with_hierarchy -----------+-----------+---------------+--------------------+---------------------------------------+----------------+--------------+---------------- user1 | PUBLIC | postgres | pg_catalog | pg_attribute | SELECT | NO | YES user1 | PUBLIC | postgres | pg_catalog | pg_index | SELECT | NO | YES user1 | PUBLIC | postgres | pg_catalog | pg_opclass | SELECT | NO | YES postgres=# select * from information_schema.usage_privileges; --自定义对象权限查询,privilege_type可看都有哪些权限 grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable -----------+-----------+----------------+--------------------+------------------------+----------------------+----------------+-------------- user1 | PUBLIC | postgres | pg_catalog | default | COLLATION | USAGE | NO user1 | PUBLIC | postgres | pg_catalog | C | COLLATION | USAGE | NO user1 | PUBLIC | postgres | pg_catalog | POSIX | COLLATION | USAGE | NO postgres=# select * from information_schema.role_usage_grants; --当前角色拥有的对象权限,privilege_type可看都有哪些权限 grantor | grantee | object_catalog | object_schema | object_name | object_type | privilege_type | is_grantable -----------+-----------+----------------+--------------------+------------------------+----------------------+----------------+-------------- user1 | PUBLIC | postgres | pg_catalog | default | COLLATION | USAGE | NO user1 | PUBLIC | postgres | pg_catalog | C | COLLATION | USAGE | NO user1 | PUBLIC | postgres | pg_catalog | POSIX | COLLATION | USAGE | NO ``` 查看schema上的权限 ```SQL --schema上有CREATE,ALTER,DROP,USAGE四种权限 SELECT u_grantor.rolname::information_schema.sql_identifier AS grantor, grantee.rolname::information_schema.sql_identifier AS grantee, current_database()::information_schema.sql_identifier AS schema_catalog, g.nspname::information_schema.sql_identifier AS schema_name, prtype::information_schema.character_data AS privilege_type, CASE WHEN pg_has_role(grantee.oid, g.nspowner, 'USAGE'::text) OR g.grantable THEN 'YES'::text ELSE 'NO'::text END::information_schema.yes_or_no AS is_grantable FROM (select nspname, nspowner, (aclexplode(COALESCE(pg_namespace.nspacl, acldefault('r'::"char", pg_namespace.nspowner)))).* from pg_namespace) g(nspname, nspowner, grantor, grantee, prtype, grantable), pg_authid u_grantor, (SELECT pg_authid.oid, pg_authid.rolname FROM pg_authid UNION ALL SELECT 0::oid AS oid, 'PUBLIC'::name AS "?column?") grantee(oid, rolname) WHERE g.grantee = grantee.oid AND g.grantor = u_grantor.oid and g.prtype = ANY (ARRAY['USAGE'::text, 'CREATE'::text, 'ALTER'::text, 'DROP'::text]) AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR pg_has_role(grantee.oid, 'USAGE'::text) OR grantee.rolname = 'PUBLIC'::name); grantor | grantee | schema_catalog | schema_name | privilege_type | is_grantable -----------+-----------+----------------+--------------------+----------------+-------------- w00567668 | w00567668 | postgres | public | USAGE | YES w00567668 | w00567668 | postgres | public | CREATE | YES w00567668 | w00567668 | postgres | public | ALTER | YES w00567668 | w00567668 | postgres | public | DROP | YES w00567668 | PUBLIC | postgres | public | USAGE | NO (5 rows) ``` 查看逻辑集群上的权限 ```SQL --逻辑集群上有USAGE,CREATE,COMPUTE三种权限 select u_grantor.rolname::information_schema.sql_identifier AS grantor, grantee.rolname::information_schema.sql_identifier AS grantee, group_name, prtype::information_schema.character_data AS privilege_type, CASE WHEN pg_has_role(grantee.oid, 10::oid, 'USAGE'::text) OR g.grantable THEN 'YES'::text ELSE 'NO'::text END::information_schema.yes_or_no AS is_grantable from ( select group_name, (aclexplode(COALESCE(group_acl, acldefault('r'::"char", 10::oid)))).* from pgxc_group) g(group_name, grantor, grantee, prtype, grantable), pg_authid u_grantor, (SELECT pg_authid.oid, pg_authid.rolname FROM pg_authid UNION ALL SELECT 0::oid AS oid, 'PUBLIC'::name AS "?column?") grantee(oid, rolname) where g.grantee = grantee.oid AND g.grantor = u_grantor.oid and g.prtype = ANY (ARRAY['USAGE'::text, 'CREATE'::text, 'COMPUTE'::text]) AND (pg_has_role(u_grantor.oid, 'USAGE'::text) OR pg_has_role(grantee.oid, 'USAGE'::text) OR grantee.rolname = 'PUBLIC'::name); grantor | grantee | group_name | privilege_type | is_grantable -----------+-----------+------------+----------------+-------------- w00567668 | w00567668 | node_group | USAGE | YES w00567668 | w00567668 | node_group | CREATE | YES w00567668 | w00567668 | node_group | COMPUTE | YES w00567668 | PUBLIC | node_group | USAGE | NO w00567668 | PUBLIC | node_group | CREATE | NO w00567668 | PUBLIC | node_group | COMPUTE | NO (6 rows) ``` ## 2. sequence是否支持cache,一次获取多个值 可以通过“CACHE”在创建sequence时指定缓存大小,暂时不能通过alter修改。 ```SQL CREATE SEQUENCE fooo_seq START WITH 5 INCREMENT BY 5 CACHE 3 CYCLE; --创建起始值为5,步长为5,缓存为3,循环使用的序列 --修改SEQUENCE暂时不支持 ``` ## 3. numeric精度 ``` NUMBERIC[(P[,S])] DECIMAL[(P[,S])] NUMBER[(P[,S])] ``` 精度p取值范围为[1,1000],标度s取值范围为[0,p]。其中p为总位数,s为小数位数 用户声明精度。每四位(十进制位)占用两个字节,然后在整个数据上加上八个字节的额外开销。 未指定精度的情况下,小数点前最大131072位,小数点后最大16383位。 开发建议: ```TEXT 1) numeric能表示更高的精度,但占用空间也大。 2) 列存表的numeric有优化,定义精度如在38以下,内部自动也用bigint实现,性能会有明显提升。 3) 开发建议:建议显式指定标度和精度,小数位为0时,建议用整数类型,不要用numeric。 ``` ## 4. uuid是如何保证唯一性的 集群内全局唯一,不同集群间可能会重。 a. 同一套集群内部使用时,uuid不会重复。 b. 数据从A集群,迁移到B集群,在B集群上也不会重复。 c. 并行运行的不同集群,同一时刻产生的uuid可能会重复。 UUID的结构组成如下: ![](https://bbs-img.huaweicloud.com/data/forums/attachment/forum/20223/15/1647326582629924461.png) UUID的使用: ``` postgres=# select sys_guid(); --生成一个UUID类型的序列号,返回类型为TEXT sys_guid ---------------------------------- 622AA549BA9404DA1F3EF757D700FFFE (1 row) ``` ## 5. 是否支持round robin方式分布的表 a. 8.1.2版本开始支持round robin分布方式,由参数default_distribution_mode控制。 b. 8.1.2版本后新建集群表的默认分布方式为round robin。 c. 从低版本升级到8.1.2版本的default_distribution_mode默认值依然为hash,如需要round robin可以在线修改配置参数。 ```SQL postgres=# \d+ t1 Table "public.t1" Column | Type | Modifiers | Storage | Stats target | Description --------+---------+-----------+---------+--------------+------------- a | integer | | plain | | Has OIDs: no Distribute By: ROUND ROBIN Location Nodes: ALL DATANODES Options: orientation=row, compression=no ``` ## 6. string_agg列转行的长度限制 内部使用text类型,最大长度为1GB。 ## 7. join + groupby时分布键的选择策略,goupby时能否指定分布键 join时可以通过hint指定表的stream方式,见产品手册“Stream方式的Hint”。例如: ```SQL select /*+ redistribute(store) */ ... --让store表做重分布 ``` group by时指定分布键暂不支持,需求规划中。 ## 8. 分布键选择规范 a. 分布列的列值应比较离散,以便数据能够均匀分布到各个DN。 b. 在没有主键或没有某一列非常离散的情况下,也可以选择多分布列,以保证数据更均匀的分布到各个DN。 c. 在满足上面原则的情况下,考虑选择查询中的连接条件为分布列,以便join任务能够下推到DN中执行,且减少DN之间的通信数据量。 参考:表的设计 https://bbs.huaweicloud.com/blogs/203219 ## 9. 行列表选择规范 a. GaussDB(DWS)可以指定两种表数据存储方式,即行存或列存。其值为COLUMN,则表的数据将以列式存储;其值为ROW,则表的数据将以行存存储。若不指定,默认值为ROW。 b. 行存储适合OLTP业务,此类型的表上交互事务比较多,一次交互会涉及表中的多个列,用行存查询效率较高。 c. 列存储适合数据仓库业务,此类型的表上会做大量的汇聚计算,且涉及的操作较少。 ## 10. explain analyze DML时会不会真正执行 会的 ``` postgres=# create table t3(a int); NOTICE: The 'DISTRIBUTE BY' clause is not specified. Using round-robin as the distribution mode by default. HINT: Please use 'DISTRIBUTE BY' clause to specify suitable data distribution column. CREATE TABLE postgres=# explain analyze insert into t3 values(100); QUERY PLAN ---------------------------------------------------------------------------------------------------------------------------- id | operation | A-time | A-rows | E-rows | Peak Memory | A-width | E-width | E-costs ----+----------------------------------------------+--------+--------+--------+-------------+---------+---------+--------- 1 | -> Data Node Scan on "__REMOTE_FQS_QUERY__" | 2.015 | 0 | 0 | 24KB | | 0 | 0.00 ====== Query Summary ===== ----------------------------------------- Coordinator executor start time: 0.302 ms Coordinator executor run time: 2.039 ms Coordinator executor end time: 0.130 ms Planner runtime: 0.131 ms Query Id: 78812993479046345 Total runtime: 2.542 ms (12 rows) postgres=# select * from t3; a ----- 100 (1 row) ``` ## 11. 执行计划如何查看 DWS数据库的SQL调优基础 https://bbs.huaweicloud.com/blogs/163514
  • [数据库] MySQL-test 框架2
    MySQL test 框架参考https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_TESTING_TOOLS.html 测试框架程序文件• mysql-test-run.pl  测试主程序 调用mysqltest测试单个用例(单个测试文件)• mysqltest  测试单个用例,被mysql-test-run.pl调用• mysql_client_test  用来测试无法被mysqltest测试的MySQL client API• mysql-stress-test.pl  用于MySQL压力测试• unit-testing facility 用于创建测试存储引擎或插件的单独的单元测试测试suite程序文件所在目录• mysqltest 源码mysqltest.cc在client目录下,编译结果在bin目录下• mysql_client_test 源码mysql_client_test.cc在testclients目录下,编译结果在bin目录下• 其他测试程序 源码在mysql-test目录下,编译结果在install目录下的mysql-test目录install/mysql-test目录结构```bash-rw-r--r--. asan.suppdrwxr-xr-x. collections # 集成与发布测试时使用,保留在源码仓中以供参考drwxr-xr-x. extradrwxr-xr-x. include # 主要版本default_xxx.cnf文件及一些将被test文件包含的.inc文件drwxr-xr-x. lib # 保存了一些.pm .t .pl文件,将作为mysql-test-run.pl的模块被调用-rw-r--r--. lsan.supplrwxrwxrwx. mtr -> ./mysql-test-run.pl # 别名或副本-rwxr-xr-x. mysql-stress-test.pl # 压力测试lrwxrwxrwx. mysql-test-run -> ./mysql-test-run.pl # 别名或副本-rwxr-xr-x. mysql-test-run.pl # 用来一次测试drwxr-xr-x. r # 存放.result期望结果文件、.reject(与.result不一致的)实际结果文件-rw-r--r--. README-rw-r--r--. README.gcov-rw-r--r--. README.stressdrwxr-xr-x. std_data # 包含一些测试使用的数据文件drwxr-xr-x. suite # 每个子目录代表一个以文件件命名的test suitedrwxr-xr-x. t # 存放测试输入文件 .cnf .inc .opt .test等文件-rw-r--r--. valgrind.suppdrwxr-xr-x. var # 存放各种测试结果信息```t目录t包含了测试case的输入文件,对于一个用例ABC可能有文件ABC.cnf指定测试case的附加配置信息ABC-client.opt提供客户端的配置ABC-master.opt即使没有涉及主从复制,也加master,如果当前运行的server的配置和-master.opt的不一样,mysql-test-run.pl就会重启server;mysql-test-run.pl也会按照opt文件的配置重启server。每个bootstrap变量必须作为--initialize选项的参数,mysql-test-run.pl才能在服务器初始化的时候识别出需要使用的变量ABC-slave.opt有主从复制是才需要ABC.testABC.resultABC.combinations为每次测试case运行提供选项段ABC-master.sh在main server启动前将被执行,win不支持,将来可能被其他机制替换ABC-slave.sh在slave server启动前将被执行,win不支持,将来可能被其他机制替换suite.opt为所有该suite内的test case提供配置,如果一个test运行多个server,则suite.opt对所有这些server都有效。该文件中的选项会被-master.opt、-slave.opt中的同选项覆盖disabled.def用来配置将被延期或禁止运行的test case,如果由于server有bug致使一些test会失败,想忽略这些test,不被mysql-test-run.pl执行,可以将这些test列到这个文件中cnf文件可以包含基础或其他配置文件!include include/default_my.cnf[mysqld.1] # 可以使用.1/.2等组后缀名区分不同server组,每个server启动的时候都默认带有组后缀名(defaults-group-suffix)Options for server mysqld.1[mysqld.2]Options for server mysqld.2[mysqltest] # 测试客户端的配置选项ps-protocol.........[ENV] # 指定测试case的环境变量SERVER_MYPORT_1= @mysqld.1.port # 定义一个SERVER_MYPORT_1环境变量,值为上段mysqld.1中的port的值SERVER_MYPORT_2= @mysqld.2.portr目录可能包含的文件ABC.resultABC.test文件的期望输出内容ABC.reject如果test case是由于输出不一致而失败的(非其他原因失败),则.reject文件中包含test case的实际输出如果--check-testcases选项打开,若test文件没有对应result文件时,mtr将对其标记为失败。--check-testcases作用检查测试用例是否有副作用。 这是通过在每个测试用例之前和之后检查系统状态来完成的。 如果有任何差异,则测试用例因此被标记为失败。类似地,当启用 --check-testcases 选项时,MTR 会对丢失的 .result 文件进行额外检查,并且没有相应 .result 文件的测试用例被标记为失败。默认情况下启用此检查。 要禁用它,请使用 --nocheck-testcases 选项。var目录用来存放各种测试运行中生成的结果文件:log文件、temp文件、trace文件、Unix socket文件等。这个目录不能被同时跑的测试所共享。suite目录该目录下每个子文件夹代表一个与文件夹同名的test suite。 每个test suite可能包含如下部分• t目录• r目录• include目录• 一个combinations格式的文件,为每次测试运行提供配置段(Controlling the Binary Log Format Used for an Entire Test Run )• 一个my.cnf格式的文件,为本suite中的所有测试提供配置项,同配置项内容会被test_name.cnf文件的所覆盖。collections目录此目录包含我们在集成和发布测试期间运行的测试运行的集合。这些文件在此上下文之外没有直接用处,但需要成为源码仓的一部分并包含在内以供参考。每个文件包含零行或多行,每行都调用一次 mysql-test-run.pl。这些调用是这样编写的• 假设perl在环境搜索路径中• 原则上任何集合都可以作为shell脚本或批处理文件运行• mysql-test目录是当前工作目录。每行格式例如 perl mysql-test-run.pl --force --timer --big-test --testcase-timeout=90 --parallel=auto --experimental=collections/default.experimental --comment=normal-big --vardir=var-normal-big --report-features --skip-test-list=collections/disabled-daily.list --unit-tests-reportunittest目录单元测试相关目录,相关于存储引擎和插件的附加文件可能存在于storage或plugin目录的子目录下。在顶层Makefile中有多个targets可用于运行测试集。make test只运行单元测试(?),其他测试集见Makefile文件。 一个“test case”是单个文件,case中可能包含多个测试命令,任意一个测试命令没有产生预期的结果都认为整个测试用例失败(预期结果包括测试某种预期的错误,例如语法错误)。test case的输出内容(test result, 和.result文件进行diff)包括• 输入的SQL语句及其输出信息• mysqltest命令(例如echo、exec)的输出结果,而命令本身不输出到结果。disable_query_log和enable_query_log命令控制是否logging输出SQL语句(.result?) disable_result_log和enable_result_log命令控制是否logging输出SQL语句的结果包括warning、error信息(.result?)mysqltest默认从其标准输入读入test case,也可以使用--test-file或-X选项显式地给定一个test case文件名。mysqltest默认向其标准输出写入test case的结果,也可以使用--result-file或-R选项来显式地指定result文件的位置。 这个配置项和--record选项共同确定mysqltest如何处理一个test case的实际和预期测试结果。• 如果一个test没有输出result,mysqltest会带着error信息退出,除非--result-file指定的文件名为空• 如果--result-file没有给出,mysqltest将发送结果到标准输出• 如果有--result-file但没有--record选项mysqltest从指定的文件中读取期望的result文件,并且和期望的result结果做比较。如果结果不匹配,mysqltest就将实际结果写到log目录下.reject文件中,并error退出,只要有可用的diff工具,就会再输出实际与预期的diff结果。• 如果--result-file和--record都给出了,则mysqltest将用实际测试结果更新到给出的文件中,该文件不需要预先存在(最开始的result文件自动生成)。mysqltest程序本身对t/r目录一无所知,这些目录下的文件,约定由mysql-test-run.pl使用,由该pl文件为每个test case以适当的参数调用mysqltest,告诉mysqltest从哪里读取输入和向哪里输出。• 需要C++运行时库mysqltest和mysql_client_test程序是用C++编写的,可以在任何可以编译MySQL本身的系统上使用,或者可以使用二进制MySQL发行版。• 需要perl测试框架的其他部分,例如 mysql-test-run.pl 是 Perl 脚本,应该在安装了 Perl 的系统上运行。• 需要diffmysqltest使用diff程序来比较预期和实际测试结果。 如果未找到diff,mysqltest会写入错误消息并转储 .result 和 .reject 文件的全部内容,以便您可以尝试确定测试未成功的原因。 如果您的系统没有diff,您可以从以下站点之一获取它: http://www.gnu.org/software/diffutils/diffutils.html  http://gnuwin32.sourceforge.net/packages/diffutils.htm • 目录不能带空格如果从完整路径包含空格字符的目录中启动,mysql-test-run.pl 将无法正常运行,因为这将会使在所有引用这个路径的不同上下文中正确处理它变得很复杂。参考 https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_MYSQL_TEST_RUN_PL.html • 尽可能多收集错误信息,再上报bughttps://dev.mysql.com/doc/refman/8.0/en/bug-reports.html. • 确保包含了mysql-test-run.pl的输出、var/log中所有的.reject文件以及diff报告• 检查单独跑这个用例是否失败• cd mysql-test• ./mysql-test-run.pl test_name如果还失败,再继续检查是否自己编译MySQL使用了--with-debug选项且运行mysql-test-run.pl是否使用了--debug选项。如果这样还失败,则连带var/tmp/master.trace文件一起上报(顺带包含系统描述、mysqld版本、如何编译该mysqld文件)。• 运行mysql-test-run.pl带--force选项,查看是否还有其他test case失败。• Result length mismatch或者Result content mismatch,就表示可能有bug或该mysql版本在某些情况下产生的结果略有不同。• 如果一个test case完全失败,应该检查var/log目录中的logs文件中的错误信息。• 如果自己编译的debug版本MySQL,出现test case失败的情况,可以运行mysql-test-run.pl加--gdb和--debug选项来调试失败原因。在CMake时可以使用-DWITH_DEBUG来指定编译debug版本的MySQL
  • [数据库] MySQL-test 框架
    MySQL test 框架参考https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_TESTING_TOOLS.html测试框架程序文件mysql-test-run.pl测试主程序 调用mysqltest测试单个用例(单个测试文件)mysqltest测试单个用例,被mysql-test-run.pl调用mysql_client_test用来测试无法被mysqltest测试的MySQL client APImysql-stress-test.pl用于MySQL压力测试unit-testing facility 用于创建测试存储引擎或插件的单独的单元测试测试suite程序文件所在目录mysqltest源码cc在client目录下,编译结果在bin目录下mysql_client_test源码cc在testclients目录下,编译结果在bin目录下其他测试程序 源码在mysql-test目录下,编译结果在install目录下的mysql-test目录install/mysql-test目录结构```bash-rw-r--r--.  asan.suppdrwxr-xr-x.  collections         # 集成与发布测试时使用,保留在源码仓中以供参考drwxr-xr-x.  extradrwxr-xr-x.  include             # 主要版本default_xxx.cnf文件及一些将被test文件包含的.inc文件drwxr-xr-x.  lib                 # 保存了一些.pm .t .pl文件,将作为mysql-test-run.pl的模块被调用-rw-r--r--.  lsan.supplrwxrwxrwx.  mtr -> ./mysql-test-run.pl              # 别名或副本-rwxr-xr-x.  mysql-stress-test.pl                    # 压力测试lrwxrwxrwx.  mysql-test-run -> ./mysql-test-run.pl   # 别名或副本-rwxr-xr-x.  mysql-test-run.pl                       # 用来一次测试drwxr-xr-x.  r                   # 存放.result期望结果文件、.reject(与.result不一致的)实际结果文件-rw-r--r--.  README-rw-r--r--.  README.gcov-rw-r--r--.  README.stressdrwxr-xr-x.  std_data            # 包含一些测试使用的数据文件drwxr-xr-x.  suite               # 每个子目录代表一个以文件件命名的test suitedrwxr-xr-x.  t                   # 存放测试输入文件 .cnf .inc .opt .test等文件-rw-r--r--.  valgrind.suppdrwxr-xr-x.  var                 # 存放各种测试结果信息```t目录t包含了测试case的输入文件,对于一个用例ABC可能有文件ABC.cnf指定测试case的附加配置信息ABC-client.opt提供客户端的配置ABC-master.opt即使没有涉及主从复制,也加master,如果当前运行的server的配置和-master.opt的不一样,mysql-test-run.pl就会重启server;mysql-test-run.pl也会按照opt文件的配置重启server。每个bootstrap变量必须作为--initialize选项的参数,mysql-test-run.pl才能在服务器初始化的时候识别出需要使用的变量ABC-slave.opt有主从复制是才需要ABC.testABC.resultABC.combinations为每次测试case运行提供选项段ABC-master.sh在main server启动前将被执行,win不支持,将来可能被其他机制替换ABC-slave.sh在slave server启动前将被执行,win不支持,将来可能被其他机制替换suite.opt为所有该suite内的test case提供配置,如果一个test运行多个server,则suite.opt对所有这些server都有效。该文件中的选项会被-master.opt、-slave.opt中的同选项覆盖disabled.def用来配置将被延期或禁止运行的test case,如果由于server有bug致使一些test会失败,想忽略这些test,不被mysql-test-run.pl执行,可以将这些test列到这个文件中cnf文件可以包含基础或其他配置文件!include include/default_my.cnf [mysqld.1]                      # 可以使用.1/.2等组后缀名区分不同server组,每个server启动的时候都默认带有组后缀名(defaults-group-suffix)Options for server mysqld.1 [mysqld.2]Options for server mysqld.2 [mysqltest]                     # 测试客户端的配置选项ps-protocol ......... [ENV]                           # 指定测试case的环境变量SERVER_MYPORT_1= @mysqld.1.port # 定义一个SERVER_MYPORT_1环境变量,值为上段mysqld.1中的port的值SERVER_MYPORT_2= @mysqld.2.portr目录可能包含的文件ABC.resultABC.test文件的期望输出内容ABC.reject如果test case是由于输出不一致而失败的(非其他原因失败),则.reject文件中包含test case的实际输出如果--check-testcases选项打开,若test文件没有对应result文件时,mtr将对其标记为失败。--check-testcases作用检查测试用例是否有副作用。 这是通过在每个测试用例之前和之后检查系统状态来完成的。 如果有任何差异,则测试用例因此被标记为失败。类似地,当启用 --check-testcases 选项时,MTR 会对丢失的 .result 文件进行额外检查,并且没有相应 .result 文件的测试用例被标记为失败。默认情况下启用此检查。 要禁用它,请使用 --nocheck-testcases 选项。var目录用来存放各种测试运行中生成的结果文件:log文件、temp文件、trace文件、Unix socket文件等。这个目录不能被同时跑的测试所共享。suite目录该目录下每个子文件夹代表一个与文件夹同名的test suite。 每个test suite可能包含如下部分t目录r目录include目录一个combinations格式的文件,为每次测试运行提供配置段(Controlling the Binary Log Format Used for an Entire Test Run)一个cnf格式的文件,为本suite中的所有测试提供配置项,同配置项内容会被test_name.cnf文件的所覆盖。collections目录此目录包含我们在集成和发布测试期间运行的测试运行的集合。这些文件在此上下文之外没有直接用处,但需要成为源码仓的一部分并包含在内以供参考。每个文件包含零行或多行,每行都调用一次 mysql-test-run.pl。这些调用是这样编写的假设perl在环境搜索路径中原则上任何集合都可以作为shell脚本或批处理文件运行mysql-test目录是当前工作目录。每行格式例如 perl mysql-test-run.pl --force --timer --big-test --testcase-timeout=90 --parallel=auto --experimental=collections/default.experimental --comment=normal-big --vardir=var-normal-big --report-features --skip-test-list=collections/disabled-daily.list --unit-tests-reportunittest目录单元测试相关目录,相关于存储引擎和插件的附加文件可能存在于storage或plugin目录的子目录下。在顶层Makefile中有多个targets可用于运行测试集。make test只运行单元测试(?),其他测试集见Makefile文件。 一个“test case”是单个文件,case中可能包含多个测试命令,任意一个测试命令没有产生预期的结果都认为整个测试用例失败(预期结果包括测试某种预期的错误,例如语法错误)。test case的输出内容(test result, 和.result文件进行diff)包括输入的SQL语句及其输出信息mysqltest命令(例如echo、exec)的输出结果,而命令本身不输出到结果。disable_query_log和enable_query_log命令控制是否logging输出SQL语句(.result?) disable_result_log和enable_result_log命令控制是否logging输出SQL语句的结果包括warning、error信息(.result?)mysqltest默认从其标准输入读入test case,也可以使用--test-file或-X选项显式地给定一个test case文件名。mysqltest默认向其标准输出写入test case的结果,也可以使用--result-file或-R选项来显式地指定result文件的位置。 这个配置项和--record选项共同确定mysqltest如何处理一个test case的实际和预期测试结果。如果一个test没有输出result,mysqltest会带着error信息退出,除非--result-file指定的文件名为空如果--result-file没有给出,mysqltest将发送结果到标准输出如果有--result-file但没有--record选项mysqltest从指定的文件中读取期望的result文件,并且和期望的result结果做比较。如果结果不匹配,mysqltest就将实际结果写到log目录下.reject文件中,并error退出,只要有可用的diff工具,就会再输出实际与预期的diff结果。如果--result-file和--record都给出了,则mysqltest将用实际测试结果更新到给出的文件中,该文件不需要预先存在(最开始的result文件自动生成)。mysqltest程序本身对t/r目录一无所知,这些目录下的文件,约定由mysql-test-run.pl使用,由该pl文件为每个test case以适当的参数调用mysqltest,告诉mysqltest从哪里读取输入和向哪里输出。需要C++运行时库mysqltest和mysql_client_test程序是用C++编写的,可以在任何可以编译MySQL本身的系统上使用,或者可以使用二进制MySQL发行版。需要perl测试框架的其他部分,例如 mysql-test-run.pl 是 Perl 脚本,应该在安装了 Perl 的系统上运行。需要diffmysqltest使用diff程序来比较预期和实际测试结果。 如果未找到diff,mysqltest会写入错误消息并转储 .result 和 .reject 文件的全部内容,以便您可以尝试确定测试未成功的原因。 如果您的系统没有diff,您可以从以下站点之一获取它: http://www.gnu.org/software/diffutils/diffutils.html http://gnuwin32.sourceforge.net/packages/diffutils.htm目录不能带空格如果从完整路径包含空格字符的目录中启动,mysql-test-run.pl 将无法正常运行,因为这将会使在所有引用这个路径的不同上下文中正确处理它变得很复杂。参考 https://dev.mysql.com/doc/dev/mysql-server/latest/PAGE_MYSQL_TEST_RUN_PL.html尽可能多收集错误信息,再上报bughttps://dev.mysql.com/doc/refman/8.0/en/bug-reports.html.确保包含了mysql-test-run.pl的输出、var/log中所有的.reject文件以及diff报告检查单独跑这个用例是否失败cd mysql-test./mysql-test-run.pl test_name如果还失败,再继续检查是否自己编译MySQL使用了--with-debug选项且运行mysql-test-run.pl是否使用了--debug选项。如果这样还失败,则连带var/tmp/master.trace文件一起上报(顺带包含系统描述、mysqld版本、如何编译该mysqld文件)。运行mysql-test-run.pl带--force选项,查看是否还有其他test case失败。Result length mismatch或者Result content mismatch,就表示可能有bug或该mysql版本在某些情况下产生的结果略有不同。如果一个test case完全失败,应该检查var/log目录中的logs文件中的错误信息。如果自己编译的debug版本MySQL,出现test case失败的情况,可以运行mysql-test-run.pl加--gdb和--debug选项来调试失败原因。在CMake时可以使用-DWITH_DEBUG来指定编译debug版本的MySQL 
  • [技术干货] Java中容易混淆的基础知识[转载]
    面向对象三大特性:继承,封装,多态封装3中修饰符:public,private,protected,给位于同一个或不同包中的对象赋予了不同的访问权限封装的一些好处通过隐藏对象的属性来保护对象内部的状态提高代码的可用性,可维护性提高模块化继承给对象提供从基类获取字段和方法的能力,基础提高代码的重用性,可以在不修改类的情况下添加新的特性多态多态就是同一函数在不同类中有不同的实现;面向对象的多态性,即“一个接口,多个方法”。多态性体现在基类中定义的属性和方法被子类继承后,可以具有不同的属性或表现方式。多态性允许一个接口被多个同类使用,弥补了单继承的不足。final,finally,finalize的区别finalfinal可以修饰类、变量、方法,修饰类表示该类不能被继承、修饰方法表示该方法不能被重写、修饰变量表示该变量是一个 常量不能被重新赋值。finallyfinally一般作用在try-catch代码块中,在处理异常的时候,通常我们将一定要执行的代码放入finally代码块中,表示不管是 否出现异常,该代码块都会执行,一般用来存放一些关闭资源的代码。finalizefinalize是一个方法,属于Object类的一个方法,而Object类是所有类的父类,该方法一般由垃圾回收器来调用,当我们调 用System.gc() 方法的时候,由垃圾回收器调用finalize(),回收垃圾,一个对象是否可回收的最后判断。int和integer的区别intint是基本数据类型integerinteger是其包装类,是一个类为了在各种类型中转换,通过各种方法调用int a = 0; String result = Integer.toString(a); //将int转换为String重载与重写的区别override重写overload重载抽象类和接口的区别接口时公开的,不能有私有的方法和变量,抽象类可以有私有的方法或私有的变量抽象类和接口的区别反射的用途以及实现反射机制所提供的功能在运行时创造一个类的对象;判断一个类所具有的成员变量和方法调用一个对象的方法生成动态代理Java反射的主要功能:确定一个对象的类取出类的modifiers,数据成员,方法,构造类,超类在运行时刻调用动态对象的方法.创建数组,数组大小和类型反射机制的理解和应用自定义注解的场景及实现登陆、权限拦截、日志处理,以及各种Java 框架,如Spring,Hibernate,JUnit 提到注解就不能不说反射,Java自定义注解是通过运行时靠反射获取注解。实际开发中,例如我们要获取某个方法的调用日志,可以通过AOP(动态代理机制)给方法添加切面,通过反射来获取方法包含的注解,如果包含日志 注解,就进行日志记录。http请求的get和post方式的区别原理区别一般我们在浏览器输入一个网址访问网站都是GET请求;再FORM表单中,可以通过设置Method指定提交方式为GET或者POST提交方式,默认为GET提交方式。HTTP定义了与服务器交互的不同方法,其中最基本的四种:GET,POST,PUT,DELETE,HEAD,其中GET和HEAD被称为安全方法,因为使用GET和HEAD的HTTP请求不会产生什么动作。不会产生动作意味着GET和HEAD的HTTP请求不会在服务器上产生任何结果。但是安全方法并不是什么动作都不产生,这里的安全方法仅仅指不会修改信息。根据HTTP规范,POST可能会修改服务器上的资源的请求。比如CSDN的博客,用户提交一篇文章或者一个读者提交评论是通过POST请求来实现的,因为再提交文章或者评论提交后资源(即某个页面)不同了,或者说资源被修改了,这些便是“不安全方法”。请求的区别GET方法会把名值对追加在请求的URL后面。因为URL对字符数目有限制,进而限制了用在 客户端请求的参数值的数目。并且请求中的参数值是可见的,因此,敏感信息不能用这种方式传递。POST方法通过把请求参数值放在请求体中来克服GET方法的限制,因此,可以发送的参数的数目是没有限制的。最后,通过POST请求传递的敏感信息对外部客户端是不可见的。参考:get和post请求方式的区别seesion与cookie的区别cookie数据存放在客户的浏览器上,session数据放在服务器上.cookie不是很安全,别人可以分析存放在本地的COOKIE并进行COOKIE欺骗考虑到安全应当使用session。设置cookie时间可以使cookie过期。但是使用session-destory(),我们将会销毁会话。session会在一定时间内保存在服务器上。当访问增多,会比较占用你服务器的性能考虑到减轻服务器性能方面,应当使用cookie。单个cookie保存的数据不能超过4K,很多浏览器都限制一个站点最多保存20个cookie。(Session对象没有对存储的数据量的限制,其中可以保存更为复杂的数据类型)JDBC流程加载JDBC驱动程序:在连接数据库之前,首先要加载想要连接的数据库的驱动到JVM(Java虚拟机), 这通过java.lang.Class类的静态方法forName(String className)实现。例如:try{ //加载MySql的驱动类 Class.forName("com.mysql.jdbc.Driver") ; }catch(ClassNotFoundException e){ System.out.println("找不到驱动程序类 ,加载驱动失败!"); e.printStackTrace() ; 成功加载后,会将Driver类的实例注册到DriverManager类中。提供JDBC连接的URL连接URL定义了连接数据库时的协议、子协议、数据源标识。书写形式:协议:子协议:数据源标识协议:在JDBC中总是以jdbc开始 子协议:是桥连接的驱动程序或是数据库管理系统名称。数据源标识:标记找到数据库来源的地址与连接端口。例如:jdbc:mysql://localhost:3306/test? useUnicode=true&characterEncoding=gbk;useUnicode=true;(MySql的连接URL)表示使用Unicode字符集。如果characterEncoding设置为 gb2312或GBK,本参数必须设置为true 。characterEncoding=gbk:字符编码方式。创建数据库的连接java.sql.DriverManager Connection代表一个数据库的连接。使用DriverManager的getConnectin(String url , String username , String password )方法传入指定的欲连接的数据库的路径、数据库的用户名和 密码来获得。例如: //连接MySql数据库,用户名和密码都是rootString url = "jdbc:mysql://localhost:3306/test" ; String username = "root" ; String password = "root" ; try{ Connection con = DriverManager.getConnection(url , username , password ) ; }catch(SQLException se){ System.out.println("数据库连接失败!"); se.printStackTrace() ; • 要执行SQL语句,必须获得java.sql.Statement实例,Statement实例分为以下3 种类型:1、执行静态SQL语句。通常通过Statement实例实现。2、执行动态SQL语句。通常通过PreparedStatement实例实现。3、执行数据库存储过程。通常通过CallableStatement实例实现。具体的实现方式:Statement stmt = con.createStatement() ; PreparedStatement pstmt = con.prepareStatement(sql) ; CallableStatement cstmt = con.prepareCall("{CALL demoSp(? , ?)}") ;执行SQL语句Statement接口提供了三种执行SQL语句的方法:executeQuery 、executeUpdate 和execute1、ResultSet executeQuery(String sqlString):执行查询数据库的SQL语句 ,返回一个结果集(ResultSet)对象。2、int executeUpdate(String sqlString):用于执行INSERT、UPDATE或 DELETE语句以及SQL DDL语句,如:CREATE TABLE和DROP TABLE等3、execute(sqlString):用于执行返回多个结果集、多个更新计数或二者组合的 语句。 具体实现的代码:ResultSet rs = stmt.executeQuery(“SELECT * FROM …”) ; int rows =stmt.executeUpdate(“INSERT INTO …”) ; boolean flag = stmt.execute(String sql) ;处理结果两种情况:1、执行更新返回的是本次操作影响到的记录数。2、执行查询返回的结果是一个ResultSet对象。• ResultSet包含符合SQL语句中条件的所有行,并且它通过一套get方法提供了对这些 行中数据的访问。• 使用结果集(ResultSet)对象的访问方法获取数据:while(rs.next()){String name = rs.getString(“name”) ;String pass = rs.getString(1) ; // 此方法比较高效}(列是从左到右编号的,并且从列1开始)关闭JDBC对象操作完成以后要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声 明顺序相反:1、关闭记录集2、关闭声明3、关闭连接对象 if(rs!=null){ // 关闭记录集 try{ rs.close(); }catch(SQLException e){e.printStackTrace(); } }try{ stmt.close(); } }catch(SQLException e){e.printStackTrace(); } if(conn!=null){ // 关闭连接对象 try{ conn.close(); }catch(SQLException e){ e.printStackTrace();20} }MVC思想M:Model 模型V:View 视图C:Controller控制器模型就是封装业务逻辑和数据的一个一个的模块,控制器就是调用这些模块的(java中通常是 用Servlet来实现,框架的话很多是用Struts2来实现这一层),视图就主要是你看到的,比如JSP 等.当用户发出请求的时候,控制器根据请求来选择要处理的业务逻辑和要选择的数据,再返回去 把结果输出到视图层,这里可能是进行重定向或转发等.equals 与 == 的区别值类型(int,char,long,boolean等)都是用==判断相等性。对象引用的话,判断引用所指的对象 是否是同一个。equals是Object的成员函数,有些类会覆盖(override)这个方法,用于判 断对象的等价性。例如String类,两个引用所指向的String都是"abc",但可能出现他们实际对应的对象并不是同一个(和jvm实现方式有关),因此用 ==判断他们可能不相等,但用equals判断一定是相等的。线程创建线程的方法及实现Java中创建线程主要有三种方式:一、继承Thread类创建线程类(1) 定义Thread类的子类,并重写该类的run方法,该run方法的方法体就代表了线程要完成的任务。因此把run()方法称为执行体。(2) 创建Thread子类的实例,即创建了线程对象。(3) 调用线程对象的start()方法来启动该线程。package com.thread; public class FirstThreadTest extends Thread{ int i = 0; //重写run方法,run方法的方法体就是现场执行体public void run() { for(;i<100;i++){ System.out.println(getName()+" "+i); } } public static void main(String[] args) { for(int i = 0;i< 100;i++) { System.out.println(Thread.currentThread().getName()+" "+i): if(i==20) { new FirstThreadTest().start(); new FirstThreadTest().start(); } } }二、通过Runnable接口创建线程类(1) 定义runnable接口的实现类,并重写该接口的run()方法,该run()方法的方法体同样是该线程的线程执行体。(2) 创建 Runnable实现类的实例的target来创建Thread对象,该Thread对象才是真正的线程对象。(3)调用线程对象的start()方法来启动该线程package com.thread; public class RunnableThreadTest implements Runnable { private int i; public void run() { for(i = 0;i <100;i++) { System.out.println(Thread.currentThread().getName()+" "+i); } } public static void main(String[] args) { for(int i = 0;i < 100;i++) { System.out.println(Thread.currentThread().getName()+" "+i); if(i==20) { RunnableThreadTest rtt = new RunnableThreadTest(); new Thread(rtt,"新线程1").start(); new Thread(rtt,"新线程2").start(); } } } } 三、通过Callable和Future创建线程(1) 创建Callable接口的实现类,并实现call()方法,该call()方法将作为线程执行体,并且有返回值。(2) 创建Callable实现类的实例,使用FutureTask类来包装Callable对象,该FutureTask对象封装了该Callable对象的call()方法的返回值。(3) 使用FutureTask对象作为Thread对象的target创建并启动新线程。(4) 调用FutureTask对象的get()方法来获得子线程执行结束后的返回值package com.thread; import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.FutureTask; public class CallableThreadTest implements Callable<Integer> { public static void main(String[] args) { CallableThreadTest ctt = new CallableThreadTest(); FutureTask<Integer> ft = new FutureTask<>(ctt); 13 for (int i = 0; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " 的循 环变量i的值" + i); if (i == 20) { new Thread(ft, "有返回值的线程").start(); } } try { System.out.println("子线程的返回值:" + ft.get()); } catch (InterruptedException e) { e.printStackTrace(); } catch (ExecutionException e) { e.printStackTrace(); } } @Override public Integer call() throws Exception 34 { int i = 0; for (; i < 100; i++) { System.out.println(Thread.currentThread().getName() + " " + i); } return i; } }采用实现Runnable、Callable接口的方式创见多线程时,优势是:线程类只是实现了 接口或 接口,还可以继承其他类。在这种方式下,多个线程可以共享同一个target对象,所以非常适合多个相同线程来处理同 一份资源的情况,从而可以将CPU、代码和数据分开,形成清晰的模型,较好地体现了面 向对象的思想。劣势是:编程稍微复杂,如果要访问当前线程,则必须使用Thread.currentThread()方法。使用继承Thread类的方式创建多线程时优势是:编写简单,如果需要访问当前线程,则无需使用Thread.currentThread()方法,直接使用this 即可获得当前线程。劣势是:线程类已经继承了Thread类,所以不能再继承其他父类。sleep() 、join()、yield()的区别一、sleep()在指定的毫秒数内让当前正在执行的线程休眠(暂停执行),此操作受到系统计时器和调度 程序精度和准确性的影响。 让其他线程有机会继续执行,但它并不释放对象锁。也就是如 果有Synchronized同步块,其他线程仍然不能访问共享数据。注意该方法要捕获异常比如有两个线程同时执行(没有Synchronized),一个线程优先级为MAX_PRIORITY,另一 个为MIN_PRIORITY,如果没有Sleep()方法,只有高优先级的线程执行完成后,低优先级 的线程才能执行;但当高优先级的线程sleep(5000)后,低优先级就有机会执行了。总之,sleep()可以使低优先级的线程得到执行的机会,当然也可以让同优先级、高优先级的 线程有执行的机会。二、join()Thread的非静态方法join()让一个线程B“加入”到另外一个线程A的尾部。在A执行完毕之前, B不能工作。保证当前线程停止执行,直到该线程所加入的线程完成为止。然而,如果它加入的线程没有 存活,则当前线程不需要停止。三、yield()yield()方法和sleep()方法类似,也不会释放“锁标志”,区别在于,它没有参数,即yield()方 法只是使当前线程重新回到可执行状态,所以执行yield()的线程有可能在进入到可执行状态 后马上又被执行,另外yield()方法只能使同优先级或者高优先级的线程得到执行机会,这也 和sleep()方法不同。再给大家推荐一本书:Java并发编程想要电子版也可以私信我线程池的几种方式newFixedThreadPool(int nThreads)创建一个固定长度的线程池,每当提交一个任务就创建一个线程,直到达到线程池的最大数 量,这时线程规模将不再变化,当线程发生未预期的错误而结束时,线程池会补充一个新的线程newCachedThreadPool()创建一个可缓存的线程池,如果线程池的规模超过了处理需求,将自动回收空闲线程,而当 需求增加时,则可以自动添加新线程,线程池的规模不存在任何限制newSingleThreadExecutor()这是一个单线程的Executor,它创建单个工作线程来执行任务,如果这个线程异常结束,会 创建一个新的来替代它;它的特点是能确保依照任务在队列中的顺序来串行执行newScheduledThreadPool(int corePoolSize)创建了一个固定长度的线程池,而且以延迟或定时的方式来执行任务,类似于Timer。private static final Executor exec=Executors.newFixedThreadPool(50); Runnable runnable=new Runnable(){ public void run(){ ... } } exec.execute(runnable); Callable<Object> callable=new Callable<Object>() { public Object call() throws Exception { return null; } } Future future=executorService.submit(callable); future.get(); // 等待计算完成后,获取结果 future.isDone(); // 如果任务已完成,则返回 true future.isCancelled(); // 如果在任务正常完成前将其取消,则返回 true future.cancel(true); // 试图取消对此任务的执行,true中断运行的任务,false 允许正在运行的任务运行完成线程的生命周期新建(New)、就绪(Runnable)、运行(Running)、阻塞(Blocked)和死亡(Dead)5种状态(1)生命周期的五种状态新建(new Thread)当创建Thread类的一个实例(对象)时,此线程进入新建状态(未被启动)。例如:Thread t1=new Thread();就绪(runnable)线程已经被启动,正在等待被分配给CPU时间片,也就是说此时线程正在就绪队列中排队 等候得到CPU资源。例如:t1.start();运行(running)线程获得CPU资源正在执行任务(run()方法),此时除非此线程自动放弃CPU资源或者有 优先级更高的线程进入,线程将一直运行到结束。死亡(dead)当线程执行完毕或被其它线程杀死,线程就进入死亡状态,这时线程不可能再进入就绪状态 等待执行。自然终止:正常运行run()方法后终止异常终止:调用**stop()**方法让一个线程终止运行堵塞(blocked)由于某种原因导致正在运行的线程让出CPU并暂停自己的执行,即进入堵塞状态。正在睡眠:用sleep(long t) 方法可使线程进入睡眠方式。一个睡眠着的线程在指定的时间过去可进入就绪状态。正在等待:调用wait()方法。(调用motify()方法回到就绪状态)被另一个线程所阻塞:调用suspend()方法。(调用resume()方法恢复)锁机制线程安全线程安全是指要控制多个线程对某个资源的有序访问或修改,而在这些线程之间没有产生冲 突。在Java里,线程安全一般体现在两个方面:1、多个thread对同一个java实例的访问(read和modify)不会相互干扰,它主要体现在关 键字synchronized。如ArrayList和Vector,HashMap和Hashtable(后者每个方法前都有synchronized关键字)。如果你在interator一个List对象时,其它线程remove一个element, 问题就出现了。2、每个线程都有自己的字段,而不会在多个线程之间共享。它主要体现在java.lang.ThreadLocal类,而没有Java关键字支持,如像static、transient那样。volatle实现原理深入分析 Volatile 的实现原理悲观锁,乐观锁是一种思想。可以用在很多方面。比如数据库方面。悲观锁就是for update(锁定查询的行)乐观锁就是 version字段(比较跟上一次的版本号,如果一样则更新,如果失败则要重复读­比较­写的操作。)JDK方面:悲观锁就是sync乐观锁就是原子类(内部使用CAS实现)本质来说,就是悲观锁认为总会有人抢我的。乐观锁就认为,基本没人抢。乐观锁是一种思想,即认为读多写少,遇到并发写的可能性比较低,所以采取在写时先读出 当前版本号,然后加锁操作(比较跟上一次的版本号,如果一样则更新),如果失败则要重 复读­比较­写的操作。CAS是一种更新的原子操作,比较当前值跟传入值是否一样,一样则更新,否则失败。CAS顶多算是乐观锁写那一步操作的一种实现方式罢了,不用CAS自己加锁也是可以的。乐观锁的业务场景及实现方式每次获取数据的时候,都不会担心数据被修改,所以每次获取数据的时候都不会进行加锁, 但是在更新数据的时候需要判断该数据是否被别人修改过。如果数据被其他线程修改,则不 进行数据更新,如果数据没有被其他线程修改,则进行数据更新。由于数据没有进行加锁, 期间该数据可以被其他线程进行读写操作。乐观锁:比较适合读取操作比较频繁的场景,如果出现大量的写入操作,数据发生冲突的可 能性就会增大,为了保证数据的一致性,应用层需要不断的重新获取数据,这样会增加大量 的查询操作,降低了系统的吞吐量。最后都看到这了,给孩子一个三连支持一下吧,Java对初学者很友好;Java资源丰富,因为它可以解决不同的问题;Java有一个庞大而友好的社区;Java无处不在,因此更容易找到第一份工作;Java开发人员缺口大,薪水很高。只要你具备能力,薪资待遇你敢要公司就敢给。链接:https://bbs.huaweicloud.com/blogs/336625