• Oracle RAC学习笔记:基本概念及入门


    Oracle RAC学习笔记:基本概念及入门
    2010年04月19日 10:39 来源:书童的博客 作者:书童 编辑:晓熊

        【技术开发 技术文章
        oracle 10g real application clusters introduction     1、什么是cluster     一个cluster是由两个或是多个独立的、通过网络连接的servers组成的。几个硬件供应商多年以来提供了Cluster性能的各种需求。一些Clusters仅仅为了提供高可用性的,在当前活动的node发生故障时转移到次节点node。另一些是为了提供分布式的连接、工作的可扩展性。另一个Cluster的共同特点是,对于一个应用程序,它可以看做是一个单独的server。同样,管理几个servers应该尽可能像管理一个server一样简单。Cluster管理器软件提供了这种功能。
        如果是single server的nodes,文件必须存储在其各自node能访问的位置。存在有几个不同拓扑结构来解决数据访问的问题,这主要依赖于Cluster设计的主要目标。
        相互连接时一个物理的网络连接,作为每个Cluster节点直接的交互通信。
        简而言之,一个Cluster就是一组独立的servers,它们共同协作,组成一个single system。
        2、什么是Oracle real Application Cluster(RAC)     RAC是一个软件可以使你通过运行多个依赖相同Database的Instance,使用Cluster硬件。数据库files被存放在物理或是逻辑上连接每个节点的磁盘上。以便于每个活动的Instance都可以对files进行读写操作。
        RAC软件管理着数据的访问。所以更改操作在Instances之间是被相互协调的,并且每个Instance看到的信息和数据镜像都是一致的。
        通过RAC结构,可以获得冗余,从而使得即使在一个系统crash或是不可访问时,应用程序也可通过其他Instance访问Database。
        3、为啥使用RAC     RAC可以高度利用标准的Cluster,降低模块servers成本。
        RAC自动的提供了服务的工作量管理。应用程序的服务可以被分组或分类,组成商业组件完成应用工作任务。RAC中的服务可以是持续的、不间断的Database操作,并为多Instance上的多个服务提供支持。可以设计services到一个或多个Instance上运行,并且交替Instances可以用于备份Instances。如果主Instance失败,Oracle会将services从失败的Instance节点移动到活动的可替代的Instance上。Oracle也会自动的通过连接进行数据装载的平衡。
        RAC利用多个廉价的computers共同提供Database的服务,就像一个大的computer一样,服务于只有大规模SMP才能提供的各种应用。
        RAC是基于共享磁盘结构的,在需求上可以增加或缩减,而不需要人为的在Cluster中进行数据的分隔。并且RAC可以简单的增加、移出Cluster中的servers。
        4、Clusters和可扩展性

        如果使用对称多处理(symmetric multiprocessing SMP)机制能够对应用程序提供透明的服务,则应该使用RAC也可以得到同样的效果,而不需要进行应用程序代码的任何改动。
        当一个节点发生失败,RAC可以排除该Database Instance和node本身,从而保证Database的完整。
        下面是一些可扩展性的例子:     *  允许更多并发的批处理。
        *  允许更大程度的并发执行。
        *  在OLTP系统中可以是连接的用户大增。
        1)可扩展性的层次:主要有四个层次     *  hardware 的可扩展性:相互连接性是它的关键,这一般依赖于较高的带宽和较低的延迟。
        *  OS的可扩展性:在OS中,同步方法可以决定系统的可扩展性。在一些情况下,硬件的潜在可扩展性会因为OS无力并发维持请求的多个资源而被丢失。
        *  Database管理系统的可扩展性:在并发结构中的一个关键因素是并发是由内部影响的还是外部进程影响的。此问题的答案影响了同步的机制。
        *  应用层次上的可扩展性:应用程序必须被明确的设计为可扩展的。当系统中如果多数情况下,每个session都在更新相同的data,则可能产生瓶颈。这不仅是指RAC,对于single-instance系统也是一样。
        需要明确的是,如果任何一个层次没有达到可扩展性,不管其他层次可扩展性多强,并发的Cluster进程都可能失败。可扩展性不足的典型原因是共享资源的访问。这使得并发的操作在此瓶颈上序列化执行。这不仅仅是RAC中的局限,而是所有结构中的局限性。
        2)scaleup和speedup

        *  scaleup是工作量和资源都成比例增加时能维持相同性能水平的能力(相应时间)
        Scaleup=(volume parallel)/(volume original)–time for ipc
        *  speedup是指通过增加资源的数量完成固定的工作量,获得执行时间成比例的缩减的效果。
        Speedup=(time original)/(time parallel)–time for ipc
        其中,ipc是进程间通信的简写——interprocess communication  

    RAC Architecture and Concepts

        1、RAC软件原理

        在一个RAC Instance中,会见到一些普通Instance中不存在的后台进程,它们主要是用于维持Database在每个Instance中的一致性。管理全局资源,具体如下:
        *  LMON:全局队列服务监控进程——Global Enqueue Service Monitor     *  LMD0:全局队列服务守护进程——Global Enqueue Service Daemon     *  LMSx:全局缓冲服务进程,x可以从0到j——Global Cache Service Processes     *  LCK0:锁进程——Lock process     *  DIAG:诊断进程——Diagnosibility process
        在Cluster层,可以找到Cluster Ready Services软件的主要进程,它们在所有平台上提供标准的Cluster接口,并实现高可用性的操作。在每个Cluster node上都可以看到如下的进程:
        *  CRSD和RACGIMON:用于高可用性操作的引擎。     *  OCSSD:提供成员节点和服务组的访问     *  EVMD:事件检测进程,由oracle用户运行管理     *  OPROCD:Cluster的监控进程
        此外还存在几个工具用于管理Cluster中全局层次上的各种资源。这些资源是ASM Instance、RAC Database、Services和CRS应用节点。本书中涉及的工具主要有Server Control(SRVCTL)、DBCA和Enterprise Manager。

        2、RAC软件存储原理

        Oracle10g的RAC安装分为两个阶段。第一阶段是安装CRS,其次是安装带有RAC组件的Database软件并创建Cluster数据库。CRS软件使用的Oracle home必须不同于RAC软件使用的home。尽管可以将Cluster中CRS和RAC软件通过使用Cluster文件系统共享存储,但是软件总是按一定规则安装在每个节点的本地文件系统中。这支持在线补丁的升级,并消除了单节点软件造成的失败。另外有两个必须存储在共享的存储设备中:
        *  voting file:其本质上是用于Cluster synchronization Services守护进程进行节点信息的监控。大小约为20MB。
        *  Oracle Cluster Registry(OCR)文件:也是CRS关键的组成部分。用于维护在Cluster中高可用性组件的信息。例如,Cluster节点列表,Cluster数据库Instance到节点的映射和CRS应用资源的列表(如Services、虚拟内部链接协议地址等)。此文件是通过SRVCTL类似的管理工具自动维护的。其大小约100MB。
        voting file和OCR file是不能被存储在ASM中的,因为它们必须在任何Oracle Instance启动前就可以被访问。并且,两者必须是在冗余的、可靠的存储设备中存放,如RAID。推荐最好的做法是将这些文件放在裸磁盘上。

        3、OCR的结构

        Cluster的配置信息是在OCR中维护的。OCR依赖分布式的共享缓存结构用于优化关于Cluster知识库的查询。在Cluster中的每个节点都通过OCR进程访问OCR缓存在其内存中维护着一个副本。事实上在Cluster中,只有一个OCR进程对共享存储中的OCR进行读写操作。此进程负责刷新(refresh)其自己拥有的本地缓存以及Cluster中其他节点的OCR cache。对于涉及到Cluster知识库的访问,OCR客户端直接访问本地OCR进程。当客户端需要更新OCR时,它们将通过本地OCR进程与那个扮演读写OCR文件的进程进行交互。
        OCR客户端应用有:Oracle通用安装器(OUI)、SRVCTL、企业管理器(EM)、DBCA、DBUA、NetCA和虚拟网络协议助理(VIPCA)。此外,OCR维护管理着CRS内部中定义的各种应用程序的资源的依赖和状态信息,特别是Database、Instance、Services和节点的应用程序。
        配置文件的名字是ocr.loc,并且配置文件变量是ocrconfig_loc。Cluster 知识库的位置是不受限于裸设备的。可以将OCR放置在由Cluster file system管理的共享存储设备上。
        note:OCR也可用于在ASM的单Instance中作为配置文件,每个节点有一个OCR。
        4、RAC Database存储原理

        与single-Instance Oracle的存储方式最主要的不同之处在于RAC存储必须将所有RAC中数据文件存放在共享设备中(裸设备或是Cluster文件系统)以便于访问相同Database的Instance能够共享。必须为每个Instance创建至少两个redo log组,并且所有的redo log组必须也存储在共享设备中,从而为了crash恢复的目的。每个Instance的在线redo log groups被称作一个Instance的在线redo 线程。
        此外,必须为每个Instance创建一个共享的undo表空间用于Oracle推荐的undo自动管理特点。每个undo表空间必须是对所有Instance共享的,主要用于恢复的目的。
        归档日志不能被存放在裸设备上,因为其命名是自动产生的,并且每个是不一致的。因此需要存储在一个文件系统中。如果使用Cluster file system(CFS),则可以在任何时间在任何node上访问这些归档文件。如果没有使用CFS,就不得不使其他Cluster成员在恢复时那些归档日志是可用的,例如通过网络文件系统(NFS)来实现。如果使用推荐的flash recovery area特性,则其必须被存储在共享目录下,以便于所有的Instance能够访问。(共享目录可以是一个ASM磁盘组,或是一个CFS)。

        5、RAC和共享存储技术     存储是网格技术中的关键组成部分。传统上,存储都直接依附在每个Server(directly attached to each individual Server DAS)上。在过去的几年来,更灵活的存储出现并得到应用,主要是通过存储空间网络或是正规的以太网来实现访问。这些新的存储方式使得多个Servers访问相同的磁盘集合成为可能,在分布式环境中,可以获得简单的存取。
        storage area network(SAN)代表了数据存储技术在这一点的演进。传统上,C/S系统中,数据被存储在Server内部或是依附它的设备中。随后,进入了network attached storage(NAS)阶段,这使得存储设备与Server和直接连接它们的网络向分离。它在SAN遵循的原则进一步允许存储设备存在于各自的网络中,并直接通过高速的媒介进行交换。用户可以通过Server系统对存储设备的数据进行访问,Server 系统与本地网络(LAN)和SAN相互连接。
        文件系统的选择是RAC的关键。传统的文件系统不支持多系统的并行挂载。因此,必须将文件存储在没有任何文件系统的裸卷标或是支持多系统并发访问的文件系统中。
        因此,三个主要的方法用于RAC的共享存储有:
        *  裸卷标:既是一些直接附加的裸设备,需要用于存储,并以block模式进程操作。
        *  Cluster file system:也需要以block模式进程存取。一个或多个Cluster file 系统可以被用于存储所有的RAC文件。
        *  自动存储管理(ASM):对于Oracle Database files,ASM是一个轻便的、专用的、最佳化的Cluster file system。

        6、Oracle Cluster file system     Oracle Cluster file system(OCFS)是一个共享文件系统,专门为Oracle RAC设计。OCFS排除了Oracle Database files被连接到逻辑磁盘上的需要,并使得所有的节点共享一个ORACLE Home,而不需每个node在本地有一个副本。OCFS卷标可以横跨一个或多共享disks,用于冗余和性能的增强。
        下面时可放入OCFS中的文件类表:        *  Oracle software的安装文件:在10g中,此设置只在windows 2000中支持。说是后面的版本会提供在Linux中的支持,但我还没具体看。
        *  Oracle 文件(控制文件、数据文件、redo logs文件,bfiles等)
        *  共享配置文件(spfile)
        *  在Oracle运行期间,由Oracle创建的文件。
        *  voting和OCR文件
        Oracle Cluster file system对开发人员和用户时免费的。可从官方网站下载。

        7、自动存储管理(ASM)     是10g的新特性。它提供了一个纵向的统一管理的文件系统和卷标管理器,专门用于建立Oracle Database 文件。ASM可以提供单个SMP机器的管理或是贯穿多个Oracle RAC的Cluster节点。
        ASM无需再手动调节I/O,会自动的分配 I/O 负载到所有的可用资源中,从而优化性能。通过允许增加Database大小而不需shutdown数据库来调节存储分配,来辅助DBA管理动态数据库环境。
        ASM可以维护数据的冗余备份,从而提高故障的容错。它也可以被安装到可靠的存储机制中。

        8、选择RAW或CFS     *  CFS的优点:对于RAC的安装和管理非常简单;对RAC使用Oracle managed files(OMF);single Oracle软件安装;在Oracle data files上可以自动扩展;当物理节点失败时,对归档日志的统一访问。
        *  裸设备的使用:一般会用于CFS不可用或是不被Oracle支持的情况下;它提供了最好的性能,不需要在Oracle和磁盘之间的中间层;如果空间被耗尽,裸设备上的自动扩展将失败;ASM、逻辑存储管理器或是逻辑卷标管理其可以简化裸设备的工作,它们也允许加载空间到在线的裸设备上,可为裸设备创建名字,从而便于管理。

        9、RAC的典型Cluster栈

        在Cluster中的每个节点都需要一个被支持的相互连接的软件协议来支持内部Instance的交互,同时需要TCP/IP支持CRS的轮询。所有的UNIX平台在千兆以太网上使用user datagram protocol(UDP)作为主要的协议并进行RAC内部Instance 的IPC交互。其他支持的特有协议包括用于SCI和Sunfire的连接交互的远程共享内存协议和超文本协议,用于超光纤交互。在任何情况下,交互必须能被平台的Oracle所辨识。
        使用Oracle clusterware,可以降低安装并支持并发症。但如果用户使用非以太交互,或开发了依赖clusterware的应用程序在RAC上,可能需要vendor clusterware。
        同交互连接一样,共享存储方案必须被当前平台的Oracle所辨识。如果在目标平台上,CFS可用,Database area和flash recovery area都可以被创建到CFS或ASM上。如果在目标平台上,CFS不可用,则Database area可以创建在ASM或是裸设备上(需要卷标管理器)并且flash recovery area必须被创建在ASM中。

        10、RAC certification Matrix:它设计用于处理任何认证问题。可以使用matrix回答任何RAC相关的认证问题。具体使用步骤如下:
        *  连接并登陆 http://metalink.oracle.com     *  点击菜单栏的“certify and availability”按钮     *  点击“view certifications by product”连接     *  选择RAC     *  选择正确的平台

        11、必要的全局资源

        一个single-Instance环境,锁坐标通向一个共享的资源就像表中的一行。lock避免了两个进程同事修改相同的资源。
        在RAC环境中,内部节点的同步时关键,因为它维持着不同节点中各自进程的一致性,避免其在同时修改相同的资源数据。内部节点的同步确保每个Instance看到buffer cache中block的最近的版本。上图中显示了当不存在加锁的情况。
        1)全局资源的协调

        cluster操作要求在所有Instance中对控制共享资源的访问进行同步。RAC使用Global Resource Directory来记录cluster Database中资源的使用信息。Global Cache Service(GCS)和Global Enqueue Service(GES)管理GRD中的信息。
        每个Instance在其本地的SGA中维护GRD的一部分。GCS和GES指定一个Instance管理特殊资源的所有信息,它被称为资源的master。每个Instance都知道resource的Instance masters。
        维护RAC的活动中的cache的依附性(cache coherency)是非常重要的。所谓cache coherency是保持在不同Oracle Instances中的多个block版本的一致性的技术。GCS通过所谓的cache融合算法来实现cache coherency。
        GES管理所有非cache 融合算法的内部Instance资源操作和Oracle入队机制的状态轨迹。GES主要的控制的资源是字典cache locks和library cache locks。同时,它还对所有死锁敏感的队列和资源起到死锁检测的作用。
        2)Global cache coordination实例

        假设某data block被第一个节点修改,成为脏数据。并且在clusterwide中,只有一个block copy版本,其内容用SCN号代替了。则具体的步骤如下:
        ① 第二个Instance视图修改该block,向GCS提出请求。
        ② GCS向block的holder(持有者)提交请求。在此,第一个Instance就是holder。
        ③ 第一个Instance接到消息,并将block发送给第二个Instance。第一个Instance保存脏buffer用于恢复的目的。block的脏镜像被称作block的past image。一个past image block将不能进一步被改变。
        ④收到block后,第二个Instance通知GCS,告知已经holds该block。
        3)write to disk coordination:example  

        在cluster结构中的Instances中的caches中,可能存在同一个block的不同的修改版本。由GCS管理的写协议确保了只有最近一个版本被写入磁盘中。它同时需要确保其他之前的版本从其他cache中被清洗。一个写磁盘的请求可以从任意一个Instance上发起,无论它是保存了block的当前版本还是过去的版本。假设第一个Instance hold过去的block镜像,请求Oracle将buffer写入磁盘,如上图,过程如下:
        ①第一个Instance发送一个写请求给GCS
        ②GCS将请求转给第二个Instance,当前该block的holder
        ③第二个Instance接到写请求后将block写入磁盘
        ④第二个Instance通知GCS,告知其写操作完成
        ⑤当接到GCS接到通知后,GCS命令所有的过去的镜像的holders删除其过去的镜像。此镜像将不会在因恢复而需要。

    12、RAC和Instance/crash recovery
        1)当一个Instance失败,当该失败被其他Instance检测到,第二个Instance将会执行下面的恢复操作:
        ①在恢复的第一阶段,GES重新灌入队列
        ②GCS也重新灌入其资源。GCS进程只重新灌入那些失去其控制的资源。在这期间,所有的GCS资源请求和写请求都临时被挂起。然而,事务可以继续修改data blocks,只要这些事务已经获得了必要的资源。
        ③当队列被重新配置后,一个活动的Instance可以获得占有该Instance恢复队列。因此,当GCS资源被重新灌入的同时,SMON确定需要被恢复的blocks的集合。这个集合被称作恢复集。因为,使用cache 融合算法,一个Instance传送这些blocks的内容到请求的Instance,而不需要将这些blocks写入磁盘。这些blocks在磁盘上的版本可能不包含其他Instance进程的data的修改操作的blocks。这意味着SMON需要合并所有失败的Instance的redo logs来确定恢复集。这是因为一个失败的线程可能导致一个在redo 中的hole(洞)需要用指定的block填补。所以失败的Instance的redo 线程不能被连续的应用。同时,活动的Instances的redo 线程不需恢复,因为SMON可以使用过去和当前的通信缓冲的镜像。
        ④用于恢复的缓冲空间被分配,并且那些之前读取redo logs被辨识的资源被声明为恢复资源。这避免了其他Instance访问这些资源。
        ⑤所有在随后的恢复操作中需要的资源被获得,并且GRD当前是不冻结的。任何不需恢复的data block现在可以被访问。所以当前系统时部分可用的。此时,假设有过去或当前的blocks镜像需要被恢复,而其在cluster Database中的其他caches中,对于这些特殊的blocks,最近的镜像是开始恢复点。如果对于要恢复的block,过去镜像和当前镜像缓冲都不在活动的Instance的caches中,则SMON将写入一个log,表明合并失败。SMON会对第三步中辨识的每个block进行恢复和写入,在恢复之后会马上释放资源,从而使更多的资源在恢复时可以被使用。
        当所有的block被恢复,占用的恢复资源被释放,则系统再次可用。
        note:在恢复中,log合并的开支和失败的Instances的数目是成比例的,并且与每个Instance的redo logs的大小有关。
        2)Instance recovery和Database availability

        上图显示了在进行Instance恢复时,每一步执行时数据库的可用程度:
        A.  RAC运行在多节点上
        B.  有节点失败被检测到
        C.  GRD的队列部分被重新设置;资源管理被重新分配到活动的nodes。此操作的执行比较快
        D.  GRD的缓冲部分被重新设置,SMON读取失败Instance的redo logs辨识那些需要恢复的blocks的集合
        E.  SMON向GRD发起请求,获得所有在需要恢复的blocks集合中的Database blocks。当请求结束,所有的其他的blocks都可被访问了
        F.  Oracle执行滚动的向前恢复。失败线程的redo logs被应用到Database,并且那些被完全恢复的blocks将马上可以被访问
        G.  Oracle执行滚回恢复。对于尚未提交的事务,undo blocks被应用到Database中
        H.  Instance的恢复完成,所有的data可以被访问

        13、有效的内部节点行级锁

        Oracle支持有效的行级锁。这些行级锁主要是在DML操作时被创建,例如UPDATE。这些锁被持有,直到事务被提交或回滚。任何请求同行的lock的进程都将被挂起。
        cache融合算法的块传输独立于这些user可见的行级锁。GCS对blocks的传输是一个底层的操作,无需当代行级锁被释放就开始进行。blocks可能被从一个Instance传输到其他其他Instances,同时该blocks可能被加锁。
        GCS提供对data blocks的访问,允许多个事务的并发进行。

        14、RAC的额外的内存需求     RAC特有的内存多数是在SGA创建时从shared pool中分配的。因为blocks可能跨越Instances被缓冲,必须要求更大的缓冲区。因此,当将single Instance的Database迁移到RAC中时,保持每个Instance的请求工作量都能通single-instance时的情况,则需要对运行RAC的Instance增大10%的buffer cache和15%的shared pool。这些值只是基于RAC大小的经验,一个初始的尝试值。一般会大于此值。
        如果正在使用推荐的自动内存管理特性,可以通过修改SGA_TARGET初始参数来设置。但考虑到同样数量的user访问被分散到多个nodes中,每个Instance的内存需求可以被降低。
        实际资源的使用可以通过查询每个Instance中的GCS和GES实体中的视图V$RESOURCE_LIMIT视图CURRENT_UTILIZATION和MAX_UTILIZATION字段,具体语句为:
        SELECT resource_name, current_utilization, max_utilization FROM v$resource_limit WHERE resource_name like ‘g%s_%’;

     15、RAC与并发执行

        Oracle的优化器是基于执行访问代价的,这就考虑了并发执行的代价,并将其作为获得理想的执行计划的一个部件。
        在RAC环境中,优化器的并发选择是由内部节点和外部节点并发两类组成的。例如,一个特殊的查询请求需要六个查询进程完成,并且在本地节点有六个并发的从属执行进程都是idle的,则查询通过使用本地资源执行,从而获得结果。这阐述了有效地内部节点并发,也无需多节点并发的查询协调的开支。如果本地节点中只有两个并发执行从属进程可用,则这两个进程和其他节点的四个进程共同执行查询。在这种情况下,内部节点和外部节点并发都被使用到,从而加速查询。
        在真实环境的决策支持应用程序中,查询不能通过各种查询servers得到较好的划分。所以有些并发执行servers完成其任务后先于其他servers变为idle状态。Oracle并发执行技术动态监测idle的进程,并将超载进程的队列表中的任务分配任务给处于idle状态的进程。这样,Oracle有效的再分配了所有进程的查询工作量。RAC进一步扩展这个效率到整个cluster上。

        16、全局动态性能视图     全局动态性能视图显示所有开启并访问RAC Database的Instances相关的信息。而标准动态性能视图只显示了本地Instance的相关信息。
        对于所有V$类型的视图,都会对应一个GV$视图,除了几个别的特殊情况。除了V$视图中的columns,GV$视图中包含了一个名为INST_ID的额外的column,显示了RAC中的Instance number。可以在任何开启的Instance上访问GV$。
        为了查询GV$视图,每个Instance上的初始PARALLEL_MAX_SERVERS初始化参数至少设置为1 。这是由于对GV$的查询使用了特殊的并发执行。并发执行的协调者运行在客户端连接的Instance上,并且每个Instance上分配一个slave用于查询其潜在的V$视图。如果有一个Instance上的PARALLEL_MAX_SERVERS被设置为0,则无法获得该node的信息,同理,如果所有的并发servers非常忙,则也无法获得结果。在以上两种情况下,不会获得提示或错误信息。
        17、RAC和Service

        18、虚拟IP地址和RAC

        当一个node完全失败,虚拟IP地址(VIP)是关于所有有效应用的。当一个节点失败,其相关的VIP自动的分派到cluster中的其他node上。当这种情况出现时:
        * crs在另外一个node的网卡的MAC地址上绑定这个ip,对用户来说是透明的。对于直接连接的客户端,会显示errors。
        *  随后发往VIP的数据包都将转向新的节点,它将给客户端发送error RST返回包。从而使客户端快速的获得errors信息,进行对其他节点的连接重试。
        如果不使用VIP,则一个node失败后,发往该节点的连接将等待10分钟的TCP过期时间。

  • 相关阅读:
    Ubuntu 16.04配置vncviewer
    Ubuntu中可以卸载的软件(持续更新)
    MySQL入门常用命令
    数据库学习笔记(一)
    TensorFlow学习笔记(一)
    ubuntu安装deb包(dpkg)
    Linux中的bin文件夹
    常对象成员和常成员函数
    this指针
    对象成员指针
  • 原文地址:https://www.cnblogs.com/timssd/p/4406570.html
Copyright © 2020-2023  润新知