首页 文章 精选 留言 我的

精选列表

搜索[快速],共10000篇文章
优秀的个人博客,低调大师

EE 2.0.3 发布,快速开发跨平台桌面软件

一个入门简单、跨平台桌面软件开发框架。 为什么使用?桌面软件(办公方向、 个人工具),仍然是未来十几年PC端需求之一,提高工作效率 🏆 码云最有价值开源项目 地址:https://gitee.com/wallace5303/electron-egg 地址:https://github.com/wallace5303/electron-egg 5分钟教程,立刻体验 特性 跨平台:一套代码,可以打包成windows版、Mac版、Linux版运行 简单:只需学习 js 语言,支持vue、react、html等前端技术 工程化:可以用服务端的开发思维,来编写桌面软件 高性能:事件驱动、非阻塞式IO 功能丰富:前端、服务端的技术场景都可以使用 功能demo:桌面软件常见功能,后续逐步集成并完善或提供demo 本次更新 增加html模式,前端支持多个html页面 增加socket服务,第三方应用可调用EE应用 增加全局config属性: userHome、appVersion、isPackaged、execDir 增加Utils工具类方法,获取socket端口,socket频道 优化应用创建逻辑 优化配置文件 优化pkg方法 优化动态端口获取 使用场景 1. 常规桌面软件 windows平台 macOS平台 linux平台 (ubuntu) 2. vue、react、web 转换成桌面软件 vue-ant-design(本地) 禅道项目管理(web项目地址) 访问官网:https://www.yuque.com/u34495/mivcfg

优秀的个人博客,低调大师

Appsmith v1.6.12 发布,应用快速构建框架

Appsmith 是一个用于构建管理面板、CRUD 应用程序和工作流的框架,它允许拖放组件来构建仪表板、使用 JavaScript 对象编写逻辑并连接到任何 API、数据库或 GraphQL 源。 目前 Appsmith 发布了 1.6.12 版本,带来如下改动: 新特性 应用程序列表页面的响应式移动 UI#10255 S3 插件:添加一次删除多个文件的命令#11119 能够通过富文本编辑器的工具栏插入媒体和更多格式#11052 支持使用自签名证书运行的 REST API #11043 禁用通过管理设置页面配置的表单登录#11234 支持 GET 请求中的请求正文#7127 添加对处理逗号分隔的浮点值的支持#11207 相机小部件中的多项增强功能#10943 Ansible 支持在 Amazon Linux 上部署#10466 Bug修复 修复复选框表单控件的顶部边距问题#10930 修复 Firestore where 子句不获取数字#10775 修复启用多选时表格小部件中的“全选和取消全选”问题#10838 修复位置更改并打开居中选项时地图图钉不居中的问题#10296 修复 Phone Input 和 Input 小部件在提交问题时未重置的问题#10860 修复文本小部件中的标题标签样式不正确的问题#10949 实体资源管理器中的条目现在会自动排序#10777 修复查询中数字占位符的顺序问题#11005 修复 API URL 编辑器,以垂直扩展长 URL#10663 修复评论图标隐藏在选项卡小部件的选项卡后面的问题#11019 修复 Google 表格因混合数据类型而合并失败的问题#11089 更新公告:https://github.com/appsmithorg/appsmith/releases/tag/v1.6.12

优秀的个人博客,低调大师

Appsmith v1.6.9 发布,应用快速构建框架

Appsmith 是一个用于构建管理面板、CRUD 应用程序和工作流的框架,它允许拖放组件来构建仪表板、使用 JavaScript 对象编写逻辑并连接到任何 API、数据库或 GraphQL 源。 目前 Appsmith 发布了 1.6.9 版本,带来如下改动: 特性 添加 Helm configMap 以更新应用程序配置 (#10157) 实体资源管理器改造:现在实体资源管理器仅显示选定的页面实体,减少了具有多个页面的应用程序的混乱。(#9811) Bug 修复 修复 Select 和 Treeselect WIdget 的验证 (#10760) 添加 iFrame ,用于在文档查看器中加载 Base64 PDF 数据 (#10770) 评估 PrivateWidgets ,以修复列表小部件子组件评估问题 (#10737) 重新验证脚本不加载的问题 (#10764) 当应用程序连接到 git 时,为重定向 url 添加分支参数,同时授权 Google Sheet (#10715) 将查询参数添加到选项/表单 (#10681) 将 meta 添加到 eval 循环,并在默认值更改时更新它 (#10401) 当代码中存在未使用的变量时显示 lint (#10599) 从源应用程序复制克隆应用程序的评估版本,以修复动态动态绑定评估,进而支持没有双重转义的转义字符 (#10702) 图标按钮移除默认的绿色 (#10573) 重置密码时清空会话 (#9955) 更新公告:https://github.com/appsmithorg/appsmith/releases/tag/v1.6.9

优秀的个人博客,低调大师

CakePHP 4.3.0 版本正式发布,PHP 快速开发框架

CakePHP 发布了4.3.0 正式版,CakePHP 是一个运用了诸如 ActiveRecord、Association Data Mapping、Front Controller 和 MVC(model–view–controller) 等著名设计模式的开源 Web 框架,用 PHP 编写,以 Ruby on Rails 的概念为模型,并在 MIT 许可下进行分发。 主要更新: 添加了一个新的 fixture 系统,它允许使用现有的migrations或 SQL 转储文件来定义架构,(包括支持 cake's migrations 和SQL 转储文件)。 加入TestSuite\HttpMockTrait,便于模拟 HTTP 客户端请求 加入LocatorAwareTrait::fetchTable(),让getTableLocator()->get()更符合人体工程学。 加入Controller::middleware(),这个方法可以定义特定于控制器的中间件,或者当前控制器的操作。 deprecationWarning()不再发出重复的警告。 Form对象支持多个验证器,并利用与 ORM 类似的接口来使用这些验证器。 Logged SQL查询现在使用布尔值,更容易粘贴到 repl 里面。 cake console指令被提取到一个新的cakephp/repl包中。 CspMiddleware可以透明地添加基于nonce的策略。 FormHelper将自动设置其他 ARIA 属性。 ORM 现在可以清楚地将用户时区的日期和时间设置为应用的时区。 CakePHP 的依赖组件league/container升级到 4.1.1 版本。 更新公告:https://github.com/cakephp/cakephp/releases/tag/4.3.0

优秀的个人博客,低调大师

深入解析,快速教会你 SQL 子查询优化!

子查询(Subquery)的优化一直以来都是 SQL 查询优化中的难点之一。关联子查询的基本执行方式类似于 Nested-Loop,但是这种执行方式的效率常常低到难以忍受。当数据量稍大时,必须在优化器中对其进行去关联化(Decoorelation 或 Unnesting),将其改写为类似于 Semi-Join 这样的更高效的算子。 前人已经总结出一套完整的方法论,理论上能对任意一个查询进行去关联化。本文结合 SQL Server 以及 HyPer 的几篇经典论文,由浅入深地讲解一下这套去关联化的理论体系。它们二者所用的方法大同小异,基本思想是想通的。 子查询简介 子查询是定义在 SQL 标准中一种语法,它可以出现在 SQL 的几乎任何地方,包括 SELECT, FROM, WHERE 等子句中。 总的来说,子查询可以分为关联子查询(Correlated Subquery)和非关联子查询(Non-correlated Subquery)。后者非关联子查询是个很简单的问题,最简单地,只要先执行它、得到结果集并物化,再执行外层查询即可。下面是一个例子: SELECT c_count, count(*) AS custdist FROM ( SELECT c_custkey, count(o_orderkey) AS c_count FROM CUSTOMER LEFT OUTER JOIN ORDERS ON c_custkey = o_custkey AND o_comment NOT LIKE '%pending%deposits%' GROUP BY c_custkey ) c_orders GROUP BY c_count ORDER BY custdist DESC, c_count DESC; 非关联子查询不在本文讨论范围之列,除非特别声明,以下我们说的子查询都是指关联子查询。 关联子查询的特别之处在于,其本身是不完整的:它的闭包中包含一些外层查询提供的参数。显然,只有知道这些参数才能运行该查询,所以我们不能像对待非关联子查询那样。 根据产生的数据来分类,子查询可以分成以下几种: 标量(Scalar-valued)子查询:输出一个只有一行一列的结果表,这个标量值就是它的结果。如果结果为空(0 行),则输出一个 NULL。但是注意,超过 1 行结果是不被允许的,会产生一个运行时异常。 标量子查询可以出现在任意包含标量的地方,例如 SELECT、WHERE 等子句里。下面是一个例子: SELECT c_custkey FROM CUSTOMER WHERE 1000000 < ( SELECT SUM(o_totalprice) FROM ORDERS WHERE o_custkey = c_custkey ) Query 1: 一个出现在 WHERE 子句中的标量子查询,关联参数用红色字体标明了 SELECT o_orderkey, ( SELECT c_name FROM CUSTOMER WHERE c_custkey = o_custkey ) AS c_name FROM ORDERS Query 2: 一个出现在 SELECT 子句中的标量子查询 存在性检测(Existential Test)子查询:特指 EXISTS 的子查询,返回一个布尔值。如果出现在 WHERE 中,这就是我们熟悉的 Semi-Join。当然,它可能出现在任何可以放布尔值的地方。 SELECT c_custkey FROM CUSTOMER WHERE c_nationkey = 86 AND EXISTS( SELECT * FROM ORDERS WHERE o_custkey = c_custkey ) Query 3: 一个 Semi-Join 的例子 集合比较(Quantified Comparision)子查询:特指 IN、SOME、ANY 的查询,返回一个布尔值,常用的形式有:x = SOME(Q)(等价于x IN Q)或X &lt;&gt; ALL(Q)(等价于x NOT IN Q)。同上,它可能出现在任何可以放布尔值的地方。 SELECT c_name FROM CUSTOMER WHERE c_nationkey <> ALL (SELECT s_nationkey FROM SUPPLIER) Query 4: 一个集合比较的非关联子查询 原始执行计划 我们以 Query 1 为例,直观地感受一下,为什么说关联子查询的去关联化是十分必要的。 下面是 Query 1 的未经去关联化的原始查询计划(Relation Tree)。与其他查询计划不一样的是,我们特地画出了表达式树(Expression Tree),可以清晰地看到:子查询是实际上是挂在 Filter 的条件表达式下面的。 实际执行时,查询计划执行器(Executor)在执行到 Filter 时,调用表达式执行器(Evaluator);由于这个条件表达式中包含一个标量子查询,所以 Evaluator 又会调用 Executor 计算标量子查询的结果。 这种 Executor - Evaluator - Executor 的交替调用十分低效!考虑到 Filter 上可能会有上百万行数据经过,如果为每行数据都执行一次子查询,那查询执行的总时长显然是不可接受的。 Apply 算子 上文说到的 Relation - Expression - Relation 这种交替引用不仅执行性能堪忧,而且,对于优化器也是个麻烦的存在——我们的优化规则都是在匹配并且对 Relation 进行变换,而这里的子查询却藏在 Expression 里,令人无从下手。 为此,在开始去关联化之前,我们引入 Apply 算子: Apply 算子(也称作 Correlated Join)接收两个关系树的输入,与一般 Join 不同的是,Apply 的 Inner 输入(图中是右子树)是一个带有参数的关系树。 Apply 的含义用下图右半部分的集合表达式定义:对于 Outer Relation RR 中的每一条数据 rr,计算 Inner Relation E(r)E(r),输出它们连接(Join)起来的结果 r⊗E(r)r⊗E(r)。Apply 的结果是所有这些结果的并集(本文中说的并集指的是 Bag 语义下的并集,也就是 UNION ALL)。 Apply 是 SQL Server 的命名,它在 HyPer 的文章中叫做 Correlated Join。它们是完全等价的。考虑到 SQL Server 的文章发表更早、影响更广,本文中都沿用它的命名。 根据连接方式(⊗⊗)的不同,Apply 又有 4 种形式: Cross ApplyA×A×:这是最基本的形式,行为刚刚我们已经描述过了; Left Outer ApplyALOJALOJ:即使 E(r)E(r) 为空,也生成一个 r∘{NULLs}r∘{NULLs}。 Semi ApplyA∃A∃:如果 E(r)E(r) 不为空则返回 rr,否则丢弃; Anti-Semi ApplyA∄A∄:如果 E(r)E(r) 为空则返回 rr,否则丢弃; 我们用刚刚定义的 Apply 算子来改写之前的例子:把子查询从 Expression 内部提取出来。结果如下: 上面的例子中,我们可以肯定 Scalar Agg 子查询有且只有一行结果,所以可以直接转成 Apply。但某些情况下,可能无法肯定子查询一定能返回 0 或 1 行结果(例如,想象一下 Query 2 如果 c_custkey 不是唯一的),为了确保 SQL 语义,还要在 Apply 右边加一个 Max1RowMax1Row 算子: Max1Row(E)=⎧⎩⎨⎪⎪Null,E,error,if |E|=0if |E|=1otherwiseMax1Row(E)={Null,if |E|=0E,if |E|=1error,otherwise 理论上,我们可以将所有的子查询转换成 Apply 算子,一个通用的方法如下: 1.如果某个算子的表达式中出现了子查询,我们就把这个子查询提取到该算子下面(留下一个子查询的结果变量),构成一个 ALOJALOJ 算子。如果不止一个子查询,则会产生多个 ALOJALOJ。必要的时候加上 Max1RowMax1Row 算子。 2.然后应用其他一些规则,将 ALOJALOJ 转换成 A×A×、A∃A∃、A∄A∄。例如上面例子中的子查询结果 XX 被用作 Filter 的过滤条件,NULL 值会被过滤掉,因此可以安全地转换成 A×A×。 下面这个例子中,Filter 条件表达式中包含 Q1Q1、Q2Q2 两个子查询。转换之后分别生成了对应的 Apply 算子。其中 Q2Q2 无法确定只会生成恰好一条记录,所以还加上了 Max1RowMax1Row 算子。 基本消除规则 第一组规则是最基本的规则,等式中的 ⊗⊗ 说明它不限制连接类型,可以是 {×,LOJ,∃,∄}{×,LOJ,∃,∄} 中的任意一个。 这两条规则是非常显而易见的,翻译成大白话就是:如果 Apply 的右边不包含来自左边的参数,那它就和直接 Join 是等价的。 下面是对 Query 3 应用规则 (2) 的例子: Project 和 Filter 的去关联化 第二组规则描述了如何处理子查询中的 Project 和 Filter,其思想可以用一句话来描述:尽可能把 Apply 往下推、把 Apply 下面的算子向上提。 注意这些规则仅处理 Cross Apply 这一种情况。其他 3 种 Apply 的变体,理论上都可以转换成 Cross Apply,暂时我们只要知道这个事实就可以了。 你可能会问:通常我们都是尽可能把 Filter、Project 往下推,为什么这里会反其道而行呢?关键在于:Filter、Project 里面原本包含了带有关联变量的表达式,但是把它提到 Apply 上方之后,关联变量就变成普通变量了!这正是我们想要的。 我们稍后就会看到这样做的巨大收益:当 Apply 被推最下面时,就可以应用第一组规则,直接把 Apply 变成 Join,也就完成了子查询去关联化的优化过程。 下面是对 Query 2 应用规则 (3) 的例子。之后再应用规则 (1),就完成了去关联化过程。 Aggregate 的去关联化 第三组规则描述如何处理子查询中的 Aggregate(即 Group By)。和上一组一样,我们的指导思想仍然是:尽可能把 Apply 往下推、把 Apply 下面的算子向上提。 下面等式中,GA,FGA,F 表示带有 Group By 分组的聚合(Group Agg),其中 AA 表示分组的列,FF 表示聚合函数的列;G1FGF1 表示不带有分组的聚合(Scalar Agg)。 这一组规则不像之前那么简单直白,我们先看一个例子找找感觉。下面是对 Query 1 运用规则 (9) 的结果: 规则 (9) 在下推 Apply 的同时,还将 ScalarAgg 变成了 GroupAgg,其中,分组列就是 R 的 key,在这里也就是 CUSTOMER 的主键 c_custkey。 如果 R 没有主键或唯一键,理论上,我们可以在 Scan 时生成一个。 为什么变换前后是等价的呢?变换前,我们是给每个 R 的行做了一次 ScalarAgg 聚合计算,然后再把聚合的结果合并起来;变换后,我们先是将所有要聚合的数据准备好(这被称为 augment),然后使用 GroupAgg 一次性地做完所有聚合。 这也解释了为什么我们要用 ALOJALOJ 而不是原本的 A×A× :原来的 ScalarAgg 上,即使输入是空集,也会输出一个 NULL。如果我们这里用 ALOJALOJ,恰好也会得到一样的行为(*);反之,如果用 A×A× 就有问题了——没有对应 ORDERS 的客户在结果中消失了! 规则 (8) 处理的是 GroupAgg,道理也是一样的,只不过原来的分组列也要留着。 ScalarAgg 转换中的细节* 细心的读者可能注意到,规则 (9) 右边产生的聚合函数是 F′F′,多了一个单引号,这暗示它和原来的聚合函数 FF 可能是有些不同的。那什么情况下会不同呢?这个话题比较深入了,不感兴趣的同学可以跳过。 首先我们思考下,GroupAgg 以及 ALOJALOJ 的行为真的和变换前一模一样吗?其实不然。举个反例: SELECT c_custkey, ( SELECT COUNT(*) FROM ORDERS WHERE o_custkey = c_custkey ) AS count_orders FROM CUSTOMER 设想一下:客户 Eric 没有任何订单,那么这个查询应当返回一个['Eric', 0]的行。但是,当我们应用了规则 (9) 做变换之后,却得到了一个['Eric', 1]的值,结果出错了! 为何会这样呢?变换之后,我们是先用 LeftOuterJoin 准备好中间数据(augment),然后用 GroupAgg 做聚合。LeftOuterJoin 为客户 Eric 生成了一个['Eric', NULL, NULL, ...]的行;之后的 GroupAgg 中,聚合函数COUNT(*)认为 Eric 这个分组有 1 行数据,所以输出了['Eric', 1]。 下面是个更复杂的例子,也有类似的问题: SELECT c_custkey FROM CUSTOMER WHERE 200000 < ( SELECT MAX(IF_NULL(o_totalprice, 42)) -- o_totalprice may be NULL FROM ORDERS WHERE o_custkey = c_custkey ) 作为总结,问题的根源在于:F(∅)≠F({NULL})F(∅)≠F({NULL}),这样的聚合函数 FF 都有这个问题。 变换后的 GroupAgg 无法区分它看到的 NULL 数据到底是 OuterJoin 产生的,还是原本就存在的,有时候,这两种情形在变换前的 ScalarAgg 中会产生不同的结果。 幸运的是,SQL 标准中定义的聚合函数 F(col)F(col) 都是 OK 的——它们都满足 F(∅)=F({NULL})F(∅)=F({NULL}),我们只要对 FF 稍加变换就能解决这个问题。 对于例子一,将COUNT(*)替换成一个对非空列(例如主键)的 Count 即可,例如:COUNT(o_orderkey); 对于例子二,需要把MIN(IF_NULL(o_totalprice, 42))分成两步来做:定义中间变量X,先用 Project 计算X = IF_NULL(o_totalprice, 42),再对聚合函数MIN(X)进行去关联化即可。 集合运算的去关联化 最后一组优化规则用来处理带有 Union(对应UNION ALL)、Subtract(对应EXCEPT ALL) 和 Inner Join 算子的子查询。再强调一遍,我们的指导思想是:尽可能把 Apply 往下推、把 Apply 下面的算子向上提。 下面的等式中,×× 表示 Cross Join,⋈R.key⋈R.key 表示按照 RR 的 Key 做自然连接:r∘e1∘e2r∘e1∘e2 。和之前一样,我们假设 RR 存在主键或唯一键,如果没有也可以在 Scan 的时候加上一个。 注意到,这些规则与之前我们见过的规则有个显著的不同:等式右边 RR 出现了两次。这样一来,要么我们把这颗子树拷贝一份,要么做成一个 DAG 的执行计划,总之会麻烦许多。 事实上,这一组规则很少能派上用场。在 [2] 中提到,在 TPC-H 的 Schema 下甚至很难写出一个带有 Union All 的、有意义的子查询。 其他 有几个我认为比较重要的点,用 FAQ 的形式列在下面。 ► 是否任意的关联子查询都可以被去关联化? 可以说是这样的,在加上少量限定之后,理论上可以证明:任意的关联子查询都可以被去关联化。 证明方法在 [1]、[3] 中都有提及。以 [1] 中为例,思路大致是: 对于任意的查询关系树,首先将关联子查询从表达式中提取出来,用 Apply 算子表示; 一步步去掉其中非基本关系算子,首先,通过等价变换去掉 Union 和 Subtract; 进一步缩小算子集合,去掉 OuterJoin、ALOJALOJ、A∃A∃、A∄A∄; 最后,去掉所有的 A×A×,剩下的关系树仅包含基本的一些关系算子,即完成了去关联化。 另一方面,现实世界中用户使用的子查询大多是比较简单的,本文中描述的这些规则可能已经覆盖到 99% 的场景。虽然理论上任意子查询都可以处理,但是实际上,没有任何一个已知的 DBMS 实现了所有这些变换规则。 ► HyPer 和 SQL Server 的做法有什么异同? HyPer 的理论覆盖了更多的去关联化场景。例如各种 Join 等算子,[3] 中都给出了相应的等价变换规则(作为例子,下图是对 Outer Join 的变换)。而在 [1] 中仅仅是证明了这些情况都可以被规约到可处理的情形(实际上嘛,可想而知,一定是没有处理的)。 另一个细节是,HyPer 中还存在这样一条规则: 其中,D=ΠF(T2)∩A(T1)(T1)D=ΠF(T2)∩A(T1)(T1),表示对 T1T1 的 Distinct Project 结果(所谓的Magic Set)。直接看等式比较晦涩,看下面的例子就容易理解了: 图中,在做 Apply 之前,先拿到需要 Apply 的列的 Distinct 值集合,拿这些值做 Apply,之后再用普通的 Join 把 Apply 的结果连接上去。 这样做的好处是:如果被 Apply 的数据存在大量重复,则 Distinct Project 之后需要 Apply 的行数大大减少。这样一来,即使之后 Apply 没有被优化掉,迭代执行的代价也会减小不少。 ► 本文说的这些变换规则,应该用在 RBO 还是 CBO 中呢?换句话说,去关联化后之后的执行计划一定比去关联化之前更好吗? 答案是,不一定。 直观的看,如果 Apply 的左边数据量比较少(例如,仅有 1 条数据),那直接带入 Apply 的右边计算反而是更好的方式。另一种情况是,右边有合适的索引,这种情况下,多次 Apply 的代价也并非不可接受。 所以把这些规则放进一个 CBO 的优化器是更合适的,优化器根据代价估计选出最优的计划来。甚至,在某些情况下,我们还会自右向左地运用这些等式,做“加关联化”。 这和用 HashJoin 还是 NestedLoopJoin 是同样的道理。事实上,NestedLoopJoin 就是 Apply 的一个特例。如果存在合适的索引,NestedLoopJoin 效率高于 HashJoin 是很常见的事情。

优秀的个人博客,低调大师

使用Oracle GoldenGate Marketplace实现数据快速同步ADW

Oracle GoldenGate 是一个实现异构 IT 环境间数据实时数据集成和复制的综合软件包。该产品集支持高可用性解决方案、实时数据集成、事务更改数据捕获、运营和分析企业系统之间的数据复制、转换和验证。 GOLDENGATE 19.1 ON MARKETPLACE功能 Oracle GoldenGate for Oracle 19.1微服务版包括对Oracle数据库版本11g,12c,18c,19c,Cloud以及本地数据库的捕获和交付支持。允许从任何Oracle数据库平台和操作系统进行远程捕获,且无需在源端和目标端数据库安装任何介质。 GoldenGate on OCI微服务架构如下: 此文将逐步介绍如何使用Oracle GoldenGate Marketplace 搭建客户已有的Oracle数据库到Oracle ADW 业务数据平台的数据实时同步。 整体步骤大致如下: 1.在ORACLE CLOUD MARKETPLACE上部署GOLDENGATE微服务 2.配置源端/目标端数据库 3.Oracle GoldenGate 微服务配置 4.数据同步测试:ORACLE12C到ADW ORACLE CLOUD MARKETPLACE上部署GOLDENGATE微服务 通过在Oracle Cloud Marketplace上使用Oracle GoldenGate微服务,可以轻松地建立和管理从本地到云,本地到本地以及云到云的数据实时复制。 1.从Oracle Cloud Marketplace主页: https://cloudmarketplace.oracle.com/marketplace 2.使用“应用程序”下的搜索框并搜索关键字GoldenGate。 3.在Oracle Cloud Marketplace中找到Oracle GoldenGate微服务列表后,您可以使用提供的TerraForm Stack部署Oracle GoldenGate。 选择版本(19.1.0.0.1默认)选择需要部署到的Compartment,单击“Launch Stack”。 4.填写Stack所需信息,其中包括Stack的名称,单击“下一步”。 5.填写以下详细信息。使用Oracle GoldenGate Microservices构建计算节点需要此信息。 显示名称 - 用于标识所有新OCI资源的显示名称。Oracle GoldenGate 主机DNS名称 - 新计算节点的域名服务的名称。 选择需要部署的Compartment. 如果要创建新网络资源,请选中此复选框。 我们选择以有的网络资源 6.选择计算资源 -支持的资源是VM.Standard2.4,VM.Standard2.8,VM.Standard2.16和VM.Standard2.24。这次选择VM.Standard2.4 分配公共IP - 选中此复选框以指示新VM是否应具有公共IP地址。 部署1 - 名称(必填) - 第一个Oracle GoldenGate部署的名称。Source 部署1 - 数据库(必填) - Oracle 12c 部署2 - 名称(可选) - 第二个Oracle GoldenGate部署的名称。Target 部署2 - 数据库(可选) - Oracle 18c 粘贴SSH公钥 - 允许SSH访问作为opc用户的公钥 7.在“确认”页面上,查看您提供的信息,然后单击“创建”。 8.名称为“OGG4ADW”Stack创建成功 9.现在可以在计算节点Instances选项卡下查看Oracle GoldenGate Microservices计算节点。 10.获取Oracle GoldenGate管理员密码 获取公共IP地址后,您必须获取Oracle GoldenGate管理员帐户(oggadmin)的密码。 Oracle GoldenGate管理员帐户(oggadmin)和密码保存在~/ogg-credentials.json文件里。 记录密码。 配置源端数据库 1.配置源或目标数据库以进行复制--源端数据库 源端数据库配置:在源端数据库打开附加日志以及OGG所需配置。 2.源端数据库: 创建OGG管理员c##ggadmin和测试用户SCOTT 3.测试用户SCOTT下,创建测试表EMP SQL> show user USER is "SCOTT" SQL> CREATE TABLE EMP (EMPNO NUMBER(4) NOT NULL, ENAME VARCHAR2(10), JOB VARCHAR2(9), MGR NUMBER(4), HIREDATE DATE, SAL NUMBER(7, 2), COMM NUMBER(7, 2), DEPTNO NUMBER(2)); Table created. SQL> ALTER TABLE EMP ADD CONSTRAINT PK_EMPNO PRIMARY KEY(EMPNO); Table altered. SQL> select count(1) from emp; COUNT(1) ---------- 0 配置目标端端数据库 1.目标端数据库配置(ADW): SQL> alter user ggadmin identified by <password> account unlock; User altered. SQL> grant dwrole to ggadmin; Grant succeeded. SQL> grant pdb_dba to ggadmin; Grant succeeded. SQL> grant create session, resource, create view, create table to ggadmin; Grant succeeded. SQL> select name,value from v$parameter where name='enable_goldengate_replication'; NAME VALUE ---------------------------------------- ---------- enable_goldengate_replication TRUE SQL> create user scott identified by <password>; User created. SQL> grant connect,resource,create table to scott; Grant succeeded. SQL> grant pdb_dba to scott; Grant succeeded. SQL> alter user scott quota unlimited on data; User altered. 2.目标端数据库上创建测试用户SCOTT和EMP表: SQL> show user USER is "SCOTT" SQL> CREATE TABLE EMP 2 (EMPNO NUMBER(4) NOT NULL, 3 ENAME VARCHAR2(10), 4 JOB VARCHAR2(9), 5 MGR NUMBER(4), 6 HIREDATE DATE, 7 SAL NUMBER(7, 2), 8 COMM NUMBER(7, 2), 9 DEPTNO NUMBER(2)); Table created. SQL> desc emp Name Null? Type ----------------------------------------- -------- ---------------------------- EMPNO NOT NULL NUMBER(4) ENAME VARCHAR2(10) JOB VARCHAR2(9) MGR NUMBER(4) HIREDATE DATE SAL NUMBER(7,2) COMM NUMBER(7,2) DEPTNO NUMBER(2) SQL> ALTER TABLE EMP ADD CONSTRAINT PK_EMPNO PRIMARY KEY(EMPNO); Table altered. SQL> select count(1) from emp; COUNT(1) ---------- 0 ORACLE GOLDENGATE MICROSERVICES更改管理员密码 1.更改OGG默认管理员OGGADMIN密码 更改OGG默认管理员密码(例如oggadmin)是保护Oracle GoldenGate Microservices部署的首要任务。需要更改oggadmin的密码,您必须先在Service Manager和Administration Server中更改它。 浏览器中输入https://<public_ip_address> 进入OGG管理页面如下: 单击”转到此网页” 输入OGG管理用户名以及保存在~/ogg-credentials.json文件里的密码 2.登录Service Manager后使用左上角的菜单图标打开菜单,从菜单中选择Administrator 在“oggadmin”编辑选项,更新oggadmin用户的密码,单击“提交”。 3.从Service Manager页面中,点击“Overview”回到控制台, 在部署框中选择Administration Server的端口号。这将导航到该部署的登录页面。 使用oggadmin用户及密码登录。也需要在每个部署的页面上更新oggadmin用户的密码。 分别点击Administration Server的端口9011和9021 4.9011和9021的每个部署的页面上更新oggadmin用户的密码 5.Oracle GoldenGate Microservices计算节点中配置环境变量: 点击下面的Source 6.源端数据库为12cR2,所以ORACLE_HOME配置为/u01/app/client/oracle12 7.目标端数据库为18c,所以ORACLE_HOME配置为/u01/app/client/oracle18 使用ORACLE GOL 使用ORACLE GOLDENGATE MICROSERVICES创建数据库连接 创建配置源端数据库连接 1.通过点击Administration Server的端口号。9011 这将导航到该部署的登录页面 打开Overview页面左上角的上下文菜单,从上下文菜单中,选择“配置”。 在“数据库”选项卡中,单击加号(+)图标以添加新凭证。 源端因为是12c多租户数据库,所以我们分别创建连接CDB和PDB的数据库凭证如下: 2.点击测试按钮,进行数据库连接测试如下:CDB 连接成功会显示Checkpoint等信息 3.点击测试按钮,进行数据库连接测试如下:PDB 在源端添加SCHEMATRANDATA 4.添加用于连接到源数据库的凭证后,必须在源端上启用事务数据日志记录。 从Oracle Database 12.1和更高版本开始,您必须使用模式指定PDB数据库。 即<pdb>.<schema> pdb1.scott 创建配置目标端数据库连接 1.通过点击Administration Server的端口号。9021 这将导航到该部署的登录页面 打开Overview页面左上角的上下文菜单,从上下文菜单中,选择“配置”。 在“数据库”选项卡中,单击加号(+)图标以添加新凭证。 目标端是ADW18c数据库,所以我们创建到数据库凭证如下: 2.点击测试按钮,进行数据库连接测试如下: 连接成功会显示Checkpoint等信息 在目标端添加检查点表 3.检查点表对于监视已应用于目标系统的检查点至关重要。无论使用何种复制,最佳做法是为目标系统启用检查点表。 Checkpoint选项中,点击添加 使用ORACLE GOLDENGATE MICROSERVICES配置进程 目前,Oracle自治数据仓库云仅支持非集成模式的Replicat。 不支持集成模式Replicat,parallel Replicat和coordindated Replicat。 配置捕获进程 在开始复制之前,您必须设置捕获进程。 Oracle GoldenGate Microservices支持三种模式的捕获进程。 Classic Extract -- OGG18c之后版本不建议使用,不支持同步到ADW/ATP Integrated Extract Initial Load Extract 配置EXTRACT进程 1.从源端管理控制台中选择添加Extract进程如下: 2.选择Integrated Extract进程,点击“Next” 3.输入Extract进程相关信息如下: 进程名:ext 数据库连接信息:源端选择CDB连接(source),创建连接参照上述创建连接部分。 Trail文件名:eg 4.选择需要注册的PDB1,点击“Next” 5.下一步填写进程相关配置信息如下:Table pdb1.scott.emp; extract ext useridalias oggadmin_pdb domain sourcepdb exttrail eg Table pdb1.scott.emp; 控制台上选择注册Extract进程到数据库,点击“创建和执行” 6.在控制台可以看到Extract进程。 配置REPLICAT进程 1.点击目标端管理服务器端口进入控制台,配置Replicat进程 2.点击添加Replicat进程 3.选择Nonintegrated Replicat 4.输入Replicat配置信息如下:目标端连接target,选择checkpoint table 5.下一步填写进程相关配置信息如下: MAP pdb1.scott.emp, TARGET MSHUTOQY95TFZPE_ADW.SCOTT.emp; 点击“创建和执行” replicat rep useridalias target domain target MAP pdb1.scott.emp, TARGET MSHUTOQY95TFZPE_ADW.SCOTT.emp; 6.在控制台可以看到Replicat进程。 数据同步测试:ORA数据同步测试:ORACLE12C到ADW 源端插入数据 SQL> select count(1) from emp; COUNT(1) ---------- 0 SQL> INSERT INTO EMP VALUES(7369, 'SMITH', 'CLERK', 7902, sysdate, 800, NULL, 20); 1 row created. SQL> INSERT INTO EMP VALUES (7499, 'ALLEN', 'SALESMAN', 7698, sysdate, 1600, 300, 30); 1 row created. SQL> commit; Commit complete. SQL> select count(1) from emp; COUNT(1) ---------- 2 从Extract进程选项中选择“详细” 在统计栏中查看同步信息 2条数据成功的被捕获 在目标端确认数据同步成功 SQL> select * from emp; EMPNO ENAME JOB MGR HIREDATE SAL COMM DEPTNO ----- ---------- ---------- ----- --------- ---------- ---------- ---------- 7369 SMITH CLERK 7902 24-JUL-19 800 20 7499 ALLEN SALESMAN 7698 24-JUL-19 1600 300 30 通过点击目标端的进程详细,统计栏显示2条数据已经插入 测试删除数据从源端数据库 SQL> select count(1) from emp; COUNT(1) ---------- 2 SQL> delete emp; 2 rows deleted. SQL> commit; Commit complete. 通过点击源端的进程详细,统计栏显示删除已经被捕获 目标端确认数据源已经被删除 SQL> select * from emp ; no rows selected 通过点击目标端的进程详细,统计栏显示删除已经被同步

优秀的个人博客,低调大师

如何在工作中快速上手Git

听说微信搜索《Java鱼仔》会变更强! 本文收录于JavaStarter ,里面有我完整的Java系列文章,学习或面试都可以看看哦 (一)Git是用来做什么的 如果你进入的是一家互联网公司,那么一定会听到版本控制这个东西,所谓版本控制就是在开发过程中对文件、代码等内容的修改历史进行记录,方便查看、备份以及回滚历史代码。 同时可以用于管理多人协同开发项目,通过版本控制实现多个人并行开发,提高开发效率。 Git就是版本控制的一种实现,同样的还有Svn等。 Git又可以称为分布式版本控制,所有的版本信息仓库全部同步到每隔用户的本地,可以离线在本地提交,在有网络的时候push到相应的服务器上即可。 (二)Git的使用 Git的使用一般都是用命令行,如果是windows电脑,安装完成之后鼠标右键可以看到git bash和git gui,建议使用git bash。mac电脑安装完成之后直接在终端使用git命令即可。 2.1 配置信息 #查看所有配置信息 git config --list #查看系统配置 git config --system --list #查看全局配置 git config --global --list 2.2 设置用户名和邮箱 git config --global user.name "javayz" git config --global user.email "xxx@qq.com" 前面两步属于git安装之后的配置部分,接下来介绍git的使用 2.3 初始化本地git仓库 如果想把本地的某个文件夹变成git仓库,只需要执行 git init 2.4 克隆远程仓库 如果想把远程仓库的代码下载到本地,只需要在某个目录下执行 git clone [url] git clone -b [branchname] [url] 其中-b表示克隆指定分支的代码 2.5 提交文件三步曲 #添加文件到暂存区 git add filename #将暂存区中的文件提交到本地 git commit -m "提交信息" git push 我们也可以使用直接对代码进行拉取和提交,更加方便。 (三)Git的工作原理 git中有四个重要的区域: 工作目录(Working Directory):平常存放项目代码的地方 暂存区(Stage):临时存放改动 资源库(Repsitory/Git Directory):提交的所有版本的数据 远程仓库(Remote Directory):代码托管的平台 工作目录-->git add files-->暂存区-->git commit-->资源库-->git push-->远程仓库 (四)Git忽略文件上传 在主目录下建立.gitignore文件可以忽略提交某些文件 *.txt #忽略所有.txt结尾的文件 !a.txt #a.txt除外 temp/ #忽略temp目录下的文件 (五)ssh免密登陆 ssh-keygen -t rsa -C "xxx@qq.com" 连续三次回车后在.ssh目录下会生成一个id_rsa和id_rsa.pub,把id_rsa.pub中的字符串保存到gitee设置中的ssh公钥中,即可免密提交下载代码 (六)分支管理 分支是分布式版本控制的核心,各个分支之间互相不关联,基本上每次版本迭代都会创建一个新的分支出来。 #列出所有分支 git branch #列出所有远程分支 git branch -r #新建一个分支,但依然停留在当前分支 git branch [branch-name] #新建一个分支,并切换到该分支 git checkout -b [branch] #合并指定分支到当前分支 git merge [branch] #删除分支 git branch -d [branch-name] #删除远程分支 git push origin --delete [branch-name] git branch -dr [remote/branch] (七)Git与Idea的集成 Idea本身就支持对Git的集成,当我们clone一个项目到本地后,用Idea打开后会发现右上角多出了git的标志: 第一个蓝色箭头表示把远程仓库的代码pull到本地。 第二个绿色对勾表示提交代码,勾选要commit和push的代码,填写提交信息,然后commit and push即可。 第三个闹钟形状的是提交历史,可查看历史提交信息。 (八)总结 对于工作来说,只需要会用Idea提交拉取代码即可。但是我们需要了解git的工作原理。我是鱼仔,我们下期再见!

优秀的个人博客,低调大师

【死磕JVM】JVM快速入门之前戏篇

简介 Java是一门可以跨平台的语言,但是Java本身是不可以实现跨平台的,需要JVM实现跨平台。javac编译好后的class文件,在Windows、Linux、Mac等系统上,只要该系统安装对应的Java虚拟机,class文件都可以运行。达到 ”一次编译,到处运行” 的效果。 什么是JVM JVM是可以运行在Java代码的虚拟的计算机,既然是虚拟的计算机,当然也包含自己的CPU、字节码指令集、寄存器、栈、垃圾回收、堆和存储方法域,我们可以理解成JVM自己就是一套操作系统。 Java从编译到执行 Virtual Machine是物理机器的软件实现。Java是用在VM上运行的WORA(Write Once Run Anywhere)概念而开发的。编译器将Java文件编译为Java .class文件,然后将.class文件输入到JVM中,JVM会加载并执行类文件,如下图所示: 1. 编译 对于Java代码来说,是对于一个java类的编译,利用java编译器(javac.exe)将源码编译成能够被JVM的类加载器加载的.class文件(字节码),字节码不是机器码,是一个中间代码,与平台无关。java编译一个类的时候,如果这个类所依赖的类还没有被编译,编译器就会先编译这个被依赖的类,然后引用,如果java编译器在指定的目录下找不到该类所依赖的类的 .class文件或者 .java源文件,就会报 "Cant found sysbol"的异常错误。 编译后的字节码文件格式主要分为两部分:常量池和方法字节码。 常量池记录的是代码出现过的(常量、类名、成员变量等)以及符号引用(类引用、方法引用,成员变量引用等); 方法字节码中放的是各个方法的字节码。 2. 执行 java类执行的过程大概分为两个步骤: 类的加载 类的执行 需要说明的一点的是:JVM主要在程序第一次运行时主动使用类的时候,才会立即去加载。换言之,JVM并不是在运行时就会把所有使用到的类都加载到内存中,而是用到,不得不加载的时候,才加载进来,而且只加载一次。 从跨平台的语言到跨语言的平台 目前有一百多种语言可以跑在Java虚拟机上.... 1、Java是跨平台的语言 意思是说程序员写代码的时候只需要写一次代码,javac编译也只编译一次,但是可以在windows上运行,也可以把打好的包放到linux或者macos上运行。 2、jvm是跨语言的平台 任何语言只要使用提供的编译器编译相应的语言,通过jvm就可以运行了 2、jvm与Java无关 任何语言只要你能编译成class就可以编译在JVM上 JVM JVM是一种规范(1)虚拟机是一种抽象的计算机,通过从实际的计算机中仿真模拟各种计算机功能来实现的。JAVA虚拟机规范是一种对JAVA虚拟机实现的规范要求,是由oracle制定的,而我们平时常说的JAVA虚拟机一般是指的一种具体的JAVA虚拟机规范的实现。比如我们最经常使用的JAVA虚拟机hotspot,其实JAVA虚拟机还有很多种实现,甚至如果你对JAVA虚拟机规范有了深入的了解而且对此有兴趣的话,可以写一个自己的JAVA虚拟机,当然这其中的难度不难想象。Java虚拟机有自己完善的硬体架构,如处理器、堆栈、寄存器等,还具有相应的指令系统。JVM屏蔽了与具体操作系统平台相关的信息,使得Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。 (2)JVM是Java程序运行的环境,同时是一个操作系统的一个应用程序进程,因此它有自己的生命周期,也有己的代码和数据空间。 (3)JVM体系主要是两个JVM的内部体系结构分为三个子系统和两大组件,分别是: 类装载(ClassLoader)子系统、执行引擎子系统和GC子系统 组件是内存运行数据区域和本地接口。 常见的JVM实现 一、Hotspot HotSpot VM,它是Sun JDK和OpenJDK中所带的虚拟机,也是目前使用范围最广的Java虚拟机。但不一定所有人都知道的是,这个目前看起来“血统纯正”的虚拟机在最初并非由Sun公司开发,而是由一家名为“Longview Technologies”的小公司设计的;甚至这个虚拟机最初并非是为Java语言而开发的,它来源于Strongtalk VM,而这款虚拟机中相当多的技术又是来源于一款支持Self语言实现“达到C语言50%以上的执行效率”的目标而设计的虚拟机,Sun公司注意到了这款虚拟机在JIT编译上有许多优秀的理念和实际效果,在1997年收购了Longview Technologies公司,从而获得了HotSpot VM。 HotSpot VM既继承了Sun之前两款商用虚拟机的优点(如前面提到的准确式内存管理),也有许多自己新的技术优势,如它名称中的HotSpot指的就是它的热点代码探测技术(其实两个VM基本上是同时期的独立产品,HotSpot还稍早一些,HotSpot一开始就是准确式GC,而Exact VM之中也有与HotSpot几乎一样的热点探测。为了Exact VM和HotSpot VM哪个成为Sun主要支持的VM产品,在Sun公司内部还有过争论,HotSpot打败Exact并不能算技术上的胜利),HotSpot VM的热点代码探测能力可以通过执行计数器找出最具有编译价值的代码,然后通知JIT编译器以方法为单位进行编译。如果一个方法被频繁调用,或方法中有效循环次数很多,将会分别触发标准编译和OSR(栈上替换)编译动作。通过编译器与解释器恰当地协同工作,可以在最优化的程序响应时间与最佳执行性能中取得平衡,而且无须等待本地代码输出才能执行程序,即时编译的时间压力也相对减小,这样有助于引入更多的代码优化技术,输出质量更高的本地代码。 在2006年的JavaOne大会上,Sun公司宣布最终会把Java开源,并在随后的一年,陆续将JDK的各个部分(其中当然也包括了HotSpot VM)在GPL协议下公开了源码,并在此基础上建立了OpenJDK。这样,HotSpot VM便成为了Sun JDK和OpenJDK两个实现极度接近的JDK项目的共同虚拟机。 在2008年和2009年,Oracle公司分别收购了BEA公司和Sun公司,这样Oracle就同时拥有了两款优秀的Java虚拟机:JRockit VM和HotSpot VM。Oracle公司宣布在不久的将来(大约应在发布JDK 8的时候)会完成这两款虚拟机的整合工作,使之优势互补,所以我们现在使用的虚拟机应该就是整合之后的虚拟机。整合的方式大致上是在HotSpot的基础上,移植JRockit的优秀特性,譬如使用JRockit的垃圾回收器与MissionControl服务,使用HotSpot的JIT编译器与混合的运行时系统。 查看JVM,我们只需要使用 java -version就可以查看了 二、Jrockit jrockit前身是BA jrockit,后被oracle收购,并免费发布,但并不开源。 jrockit可以看做是兼容标准的JDK基础上的JVM,同原有的JVM相比,jrockit声称在速度上有显著的提高(甚至超过70%),jrockit在速度上的优势使其应用在时间敏感的领域内,如军事,电信,控制等,这也得益于其针对不同处理器架构所做的优化,曾经号称是世界上最快的JVM 三、J9 J9 是一个IBM推出的Java虚拟机和类库,J9在IBM的从移动设备到企业解决方案中广泛的被使用 四、Microsoft VM 来自于微软的JVM 五、TaobaoVM hotspot深度定制版,除了在性能优化方面下足了功夫,TaobaoVM还在HotSpot的基础之上大幅度扩充了一些特定的增强实现。比如创新的GCIH(GC invisible heap)技术实现off-heap,这样一来就可以将生命周期较长的Java对象从heap中移至heap之外,并且GC不能管理GCIH内部的Java对象,这样做最大的好处就是降低了GC的回收平率以及提升了GC的回收效率,并且GCIH中的对象还能够在多个Java虚拟机进程中实现共享。其他扩充技术还有利用PMU hardware的Java profiling tool和诊断协助功能等。 据说淘宝里面大概有十个人能够手写TaobaoVM,都是P9 P10级别的 六、LiquidVM 直接针对于硬件 七、azul zing 最新垃圾回收的业界标杆,性能极高,但是这个是收费的,并且只有土豪才用的起。 官网:www.azul.com JDK JRE JVM JVM : 英文名称(Java Virtual Machine),就是我们耳熟能详的 Java 虚拟机。它只认识 xxx.class 这种类型的文件,它能够将 class 文件中的字节码指令进行识别并调用操作系统向上的 API 完成动作。所以说,jvm 是 Java 能够跨平台的核心,具体的下文会详细说明。 JRE : 英文名称(Java Runtime Environment),我们叫它:Java 运行时环境。它主要包含两个部分,jvm 的标准实现和 Java 的一些基本类库。它相对于 jvm 来说,多出来的是一部分的 Java 类库。 JDK : 英文名称(Java Development Kit),Java 开发工具包。jdk 是整个 Java 开发的核心,它集成了 jre 和一些好用的小工具。例如:javac.exe,java.exe,jar.exe 等。 显然,这三者的关系是:一层层的嵌套关系。 JDK>JRE>JVM 为什么我们的电脑在装完 jdk 后会有两个版本的 jre?没有联系。甚至准确的来说,它俩是一样的,无论是用哪一个都是可以的。只是很多人习惯将会单独安装另一个 jre,虽然单独安装的 jre 也并没有被使用,原因可能就是刚开始大家都不清楚 jdk 和 jre 之间的关系,所以就默认的都安装上了。 小结 今天的JVM知识点就讲完了,有疑问的小伙伴可以留言或评论 怕什么真理无穷,进一步有进一步的欢喜,我是牧小农,大家加油!!!

资源下载

更多资源
优质分享App

优质分享App

近一个月的开发和优化,本站点的第一个app全新上线。该app采用极致压缩,本体才4.36MB。系统里面做了大量数据访问、缓存优化。方便用户在手机上查看文章。后续会推出HarmonyOS的适配版本。

Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Nacos

Nacos

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称,一个易于构建 AI Agent 应用的动态服务发现、配置管理和AI智能体管理平台。Nacos 致力于帮助您发现、配置和管理微服务及AI智能体应用。Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据、流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

用户登录
用户注册