进度间通讯,基础架构

By admin in 4858.com on 2019年4月12日

运用SendMessage向另一进度发送WM_COPYDATA消息

壹.先是看望哪些是OGG,以及OGG的用处

壹.戈尔德engate 出品家庭

  •  高尔德engate:宗旨产品 
  •  高尔德engate Director :现已改名称为高尔德engate Management
    Pack,为高尔德engate提供温馨的GUI配置管理界面。 
  •  戈尔德engate Veridata
    :为高尔德engate源端和对象端提供数据比对和校验的效率

  注意:那八个产品并不是一个封装的成品,需分开单独购买

转载:

Send端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;

namespace SentTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            this.Title = "发送窗口";
        }

        const int WM_COPYDATA = 0x004A;

        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        [DllImport("User32.dll")]
        public static extern int SendMessage(int hwnd, int msg, int wParam, ref COPYDATASTRUCT IParam);
        [DllImport("User32.dll")]
        public static extern int FindWindow(string lpClassName, string lpWindowName);

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            String strSent = "需要发送的信息";

            int WINDOW_HANDLE = FindWindow(null, "接收窗口");
            if (WINDOW_HANDLE != 0)
            {
                byte[] arr = System.Text.Encoding.Default.GetBytes(strSent);
                int len = arr.Length;
                COPYDATASTRUCT cdata;
                cdata.dwData = (IntPtr)100;
                cdata.lpData = strSent;
                cdata.cData = len + 1;
                SendMessage(WINDOW_HANDLE, WM_COPYDATA, 0, ref cdata);
            }
        }
    }
}

      不难的来讲 Oracle 戈尔德en Gate
(简称OGG)是1种基于日志的结构化数据复制备份软件,它经过解析源数据库在线日志或归档日志获得多少的增量变化,再将这几个生成采用到对象数据库,从而达成源数据库与指标数据库同步。OGG能够超过不通平台(包含不通操作系统,数据库)完成大气数据亚秒一级的实时复制,从而在能够在应急系统、在线民报告表、实时数据仓库供应、交易跟踪、数据同步、集中/分发、容灾、数据库升级和移植、双事务大旨等多少个现象下利用。同时,OGG能够完结一对壹、广播(壹对多)、聚合(多对1)、双向、点对点、级联等种种灵活的拓扑结构

2.戈尔德enGate的技术架构

  和价值观的逻辑复制一样,Oracle 戈尔德enGate实现原理是透过抽取源端的redo
log或然archive
log,然后通过TCP/IP投递到指标端,最终解析还原应用到目的端,使指标端达成同源端数据同步。下图展现了Oracle
高尔德enGate的技能架构。

4858.com 1

 

Get端:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Runtime.InteropServices;
using System.Windows.Interop;

namespace GetTest
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        IntPtr hwnd;
        public MainWindow()
        {
            InitializeComponent();
            this.Title = "接受窗口";

            this.Loaded += new RoutedEventHandler(MainWindow_Loaded);
            this.Closed += new EventHandler(MainWindow_Closed);
        }

        void MainWindow_Loaded(object sender, RoutedEventArgs e)
        {
            //窗口加载完毕才可用,否则会报错。
            hwnd = new WindowInteropHelper(this).Handle;
            HwndSource source = HwndSource.FromHwnd(hwnd);
            if (source != null) source.AddHook(WndProc);
        }

        void MainWindow_Closed(object sender, EventArgs e)
        {
            try
            {
                HwndSource.FromHwnd(hwnd).RemoveHook(WndProc);
            }
            catch (Exception)
            {

                throw;
            }

        }

        const int WM_COPYDATA = 0x004A;//WM_COPYDATA消息的主要目的是允许在进程间传递只读数据。
        //Windows在通过WM_COPYDATA消息传递期间,不提供继承同步方式。
        //其中,WM_COPYDATA对应的十六进制数为0x004A
        public struct COPYDATASTRUCT
        {
            public IntPtr dwData;
            public int cData;
            [MarshalAs(UnmanagedType.LPStr)]
            public string lpData;
        }

        //wpf用此方法
        private IntPtr WndProc(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled)
        {
            if (msg == WM_COPYDATA)
            {
                COPYDATASTRUCT cdata = new COPYDATASTRUCT();
                Type mytype = cdata.GetType();
                cdata = (COPYDATASTRUCT)Marshal.PtrToStructure(lParam, mytype);
                this.textBox1.Text = cdata.lpData;
            }
            return IntPtr.Zero;
        }

        //WinFrom用此方法
        /* protected override void DefWndProc(ref Message m)
        {
            switch (m.Msg)
            {
            case WM_COPYDATA:
                COPYDATASTRUCT cdata = new COPYDATASTRUCT();
                Type mytype = cdata.GetType();
                cdata = (COPYDATASTRUCT)m.GetLParam(mytype);
                this.textBox1.Text = cdata.lpData;
                break;
            default:
                base.DefWndProc(ref m);
                break;
            }
        } */
    }
}

 

2.1 Manager进程   

  Manager进程是戈尔德enGate的主宰进程。Manager进度运转在源端和对象端上,它重要有以下多少个地点的效用:运营、
监察和控制、重启高尔德enGate的其它进程,报告错误及事件,分配数据存款和储蓄空间,发表阈值报告等。
每一个源端只怕指标端有且
只好存在一个Manager过程。其运维情况有二种即RUNNING(正在运作)和STOPPED(已经告一段落)。

昨天跟人谈到socketpair的标题,上午归来写了个程序验证下团结的估算!

参照文书档案:

c# 进度间同步达成进程之间通信的两种办法

二.OGG的逻辑结构图

2.2 Extract进程  

  Extract进度运维在数据库源端,负责从源端数据表或许日志中抓获数据。
在最初的高尔德enGate版本中,它壹般被称为
Collect进度。依据其所属的等级不一样,Extract的效果能够遵照时间来划分:

  •  在开始数据装载阶段,Extract过程一贯从源端的数额表中抽取所有数据。
  •  伊始数据同步实现现在,Extract进度负责捕获源端数据的变迁(DML和DDL)。

   Extract进度利用其内在的checkpoint机制,周期性地检查并记下其读写的岗位,常常是写入到3个本地的trail文件。这种机制是为了有限支撑即便Extract进度终止或然操作系统宕机,重新运行Extract进度后,高尔德enGate能够苏醒到在此之前的气象,
从上1个断点处继续往下运维,而不会有此外数据损失。extract进度会优选online
log。  

  其运作意况包罗STOPPED(不荒谬甘休)、STA奥迪Q5TING(正在起步)、RUNNING(正在运维)、ABENDED(Abnomal
End的缩写,表示11分截止)。

    
先说说笔者的明亮:socketpair创制了一对无名的套接字描述符(只还好AF_UNIX域中央银行使),描述符存款和储蓄于贰个二元数组,eg.
s[2]
.这对套接字能够开展双工通讯,每三个描述符既可以读也足以写。这几个在同三个历程中也能够拓展通讯,向s[0]中写入,就能够从s[1]进度间通讯,基础架构。中读取(只能从
s[1]中读取),也足以在s[1]中写入,然后从s[0]中读取;可是,若未有在0端写入,而从一端读取,则一端的读取操作会阻塞,尽管在一端写入,也
不能够从一读取,还是阻塞;反之亦然……

4858.com 2

2.3 Pump进程  

  Pump进度运维在数据库源端,其成效十三分简单。
借使源端使用了地点的trail文件,那么Pump进度就会把trail以数据块的款型通过TCP/IP协议发送到目的端,那日常也是引入的措施。 
Pump进程本质是Extract进度的一种很是情势,假设不应用trail文件,那么就是Extract进度在抽取完数据今后,直接投递到指标端。

  与Pump进程相呼应的叫做Server
Collector进程,那些进程不须求关心,因为在骨子里的操作中无需任何配置,所以它是晶莹剔透的。它运营在目标端,其任务就是把Extract/Pump投递过来的数额块重新组建成trail文件,人们称作远程trail文件。

      验证所用代码:

如上海教室所示,OGG包罗叁大主要进程Exract,Manager,Replicat等经过:

2.4 Trail文件

  为了更使得的、更安全的把数据库事务音讯从源端投递到指标端,戈尔德enGate引入trail文件的概念。前边提到的Extract抽取完数据现在,高尔德enGate会将抽取的政工新闻转化成的1种GoldenGate专有格式的文本,源、指标两端都会存在那种文件,源端存放的trail文件叫本地trail文件,目的端存放的trail文件叫远程trail文件。 

  trail文件存在的目标意在幸免单点故障,将业务消息持久化,并且利用checkpoint机制来记录其读写地方。假使故障发生,则数据能够依照checkpoint记录的职位来重传。 
 Trail文件并不总是必须的。人们得以在配置Extract进度的时候经过TCP/IP协议直接把日志的音信投递到目的端。但是并不引入这么做,因为假如发生系统宕机可能网络故障,则有希望引致数据的丢失。

    #include <stdio.h> 
    #include <string.h> 
    #include <unistd.h> 
    #include <sys/types.h> 
    #include <error.h> 
    #include <errno.h> 
    #include <sys/socket.h> 
    #include <stdlib.h> 

    #define BUF_SIZE 30 

    int main(){ 
            int s[2]; 
            int w,r; 
            char * string = "This is a test string"; 
            char * buf = (char*)calloc(1 , BUF_SIZE); 

            if( socketpair(AF_UNIX,SOCK_STREAM,0,s) == -1 ){ 
                    printf("create unnamed socket pair failed:%s\n",strerror(errno) ); 
                    exit(-1); 
            } 

            /*******test in a single process ********/ 
            if( ( w = write(s[0] , string , strlen(string) ) ) == -1 ){ 
                    printf("Write socket error:%s\n",strerror(errno)); 
                    exit(-1); 
            } 
            /*****read*******/ 
            if( (r = read(s[1], buf , BUF_SIZE )) == -1){ 
                    printf("Read from socket error:%s\n",strerror(errno) ); 
                    exit(-1); 
            } 
            printf("Read string in same process : %s \n",buf); 
              if( (r = read(s[0], buf , BUF_SIZE )) == -1){ 
                              printf("Read from socket s0 error:%s\n",strerror(errno) ); 
                                              exit(-1); 
                                                      } 
                                                      printf("Read from s0 :%s\n",buf); 

            printf("Test successed\n"); 
            exit(0); 
    } 

 

2.5 Replicat进程

  Replicat进度,日常把它称作应用进度。运转在目的端,是多少传递的末梢1站,负责读取目的端trail文件中的内容,并将其分析为DML或DDL语句,然后采纳到指标数据库中。 
和Extract进程一样,Replicat也有个中间的checkpoint机制,保障进度重新起动后得以从上次记录的岗位上马重操旧业,而过多据损失的高风险。 
它的周转情状和Extract进程1致,包含STOPPED、STA奇骏TING、RUNNING、ABENDED。

 

1.manager进程
(MGR)

三.GoldenGate的目录

 —-整理自网络

     若fork子进度,然后在服进度关闭叁个描述符eg. s[1]
,在子进程中再关闭另2个 eg. s[0]  
 ,则足以兑现父子进度之间的双工通讯,两端都可读可写;当然,如故遵守和在同3个历程之间工作的标准化,一端写,在另一端读取;

 
 Manager进度是高尔德enGate的操纵进程,运转在源端和对象端上,在指标端和源端有且唯有3个manager进度.

    
那和pipe有必然的区别,pipe是单工通讯,壹端可能是读端要么是写端,而socketpair达成了双工套接字,也就不曾所谓的读端和写端的区分

 
 它最主要功用有以下几个地点:

证北宋码:

     
运维、监察和控制、重启高尔德engate的其余进程,报告错误及事件,分配数据存款和储蓄空间,发布阀值报告等.

    #include <stdio.h> 
    #include <string.h> 
    #include <unistd.h> 
    #include <sys/types.h> 
    #include <error.h> 
    #include <errno.h> 
    #include <sys/socket.h> 
    #include <stdlib.h> 

    #define BUF_SIZE 30 

    int main(){ 
            int s[2]; 
            int w,r; 
            char * string = "This is a test string"; 
            char * buf = (char*)calloc(1 , BUF_SIZE); 
            pid_t pid; 

            if( socketpair(AF_UNIX,SOCK_STREAM,0,s) == -1 ){ 
                    printf("create unnamed socket pair failed:%s\n",strerror(errno) ); 
                    exit(-1); 
            } 

            /***********Test : fork but don't close any fd in neither parent nor child process***********/ 
            if( ( pid = fork() ) > 0 ){ 
                    printf("Parent process's pid is %d\n",getpid()); 
                 close(s[1]); 
                    if( ( w = write(s[0] , string , strlen(string) ) ) == -1 ){ 
                            printf("Write socket error:%s\n",strerror(errno)); 
                            exit(-1); 
                    } 
            }else if(pid == 0){ 
                    printf("Fork child process successed\n"); 
                    printf("Child process's pid is :%d\n",getpid()); 
                    close(s[0]); 
            }else{ 
                    printf("Fork failed:%s\n",strerror(errno)); 
                    exit(-1); 
            } 

            /*****read***In parent and child****/ 
            if( (r = read(s[1], buf , BUF_SIZE )) == -1){ 
                    printf("Pid %d read from socket error:%s\n",getpid() , strerror(errno) ); 
                    exit(-1); 
            } 
            printf("Pid %d read string in same process : %s \n",getpid(),buf); 
            printf("Test successed , %d\n",getpid()); 
            exit(0); 
    } 

 

 

2.extract进程(EXT)

上述代码中在老爹和儿子进程之间各关闭了三个描述符,则在父进度写可从子进程读取,反之若子进度写,父进度同样能够读取;我们能够作证下

 
 Extract运转在数据库源端,负责从源端数据表或者日志中抓获数据。

别的,作者也测试了在老爹和儿子进度中都不close(s[1]),也正是维持七个读端,则父进度能够读到string串,但子进度读取空串,也许子进度先读了数额,父进程阻塞于read操作!

 
 Extract的职能能够遵守表来时间来划分:

 

 
 1.起来时间装载阶段:在开头数据装载阶段,Extract进度一贯从源端的数目表中抽取数据.

之所以子进度能读取父进程的string,是因为fork时,子进度继续了父进度的文本讲述符的,同时也就获取了贰个和父进度指向相同文件表项的指
针;若父亲和儿子进程均不倒闭读端,因为指向相同的文书表项,那八个经过就有了竞争关系,争相读取这一个字符串.父进度read后将数据转到其选取缓冲区,而子进度就得不到了,只有壹份数据拷贝(若将父进度阻塞1段时间,则接受数额的就是子进程了,已经获得验证,让父进度sleep(三),子进度取得
string,而父进度取得不到而是阻塞)

 
 贰.手拉手转移捕获阶段:起头数据同步到位之后,Extract进度负责捕获源端数据的变更(DML和DDL)

 

 

有网友"笨笨"回复:

只是OGG并不是对全数的数据库都援助ddl操作

“若将父进程阻塞壹段时间,则收取数量的正是子进度了,已经获得认证,让父进度sleep(三),子进度取得string,而父进度取得不到”

 
 Extract进度会捕获全部已布署的供给一块的指标变化,但只会将已提交的业务发送到远程的trail文件用于共同。当事情提交时,全体和该事务相关的日志记录被以作业为单元顺序的笔录到trail文件中。Extract进度利用其内在的checkpoint机制,周期性的笔录其读写的地方,达成断点同步。通过上边包车型地铁三个机制,就可以保险数据完整性.

本身表明的图景是,父进度平昔不通在read上。作者想不亮堂,为啥那时候父进程不可能读取数据呢。
而上一种情景,父进程先读取数据,子进度仍旧可以读取数据(数据为空),但子进度不会堵塞在read上。

   三个Extract
进度能够而且对分化对象实行同步操作。例如,能够在多少个extract进度抽取并向目的端爆发工作数据的同时,利用另1个extract进度抽取的数目做报表。只怕,八个extract进程可以使用八个trail文件,同时抽取并并行传输给四个replicat进度以进步同步品质.

关于这么些题材,解释如下:

 
 Extract进度的动静:Stopped(经常结束),Starting(正在运营),Running(正在运维),Abended(Abnomal
End缩写,标示十分停止)

1.该网络朋友说的情事真正存在,假设先让子进度sleep,此时父进度取得多少,子进度被升迁未来读到EOF重临;假设让父进度sleep先,子进程先获取数据,之后父进度被唤醒却是一直不通不可能再次来到.按理来说那三种情状应当没差别,这些区别下文描述.

 

2.对此网上朋友提到难题的那个测试,笔者早期的指标是想注解假诺通过发生子进程的艺术,对三个写端同时有七个读端,那这一个读端之间相互竞争.大家得以用
个更有说服力的测试方法来探望这么些难点.原来的测试是让叁个经过sleep然后另2个历程读完全体字符,能够看出今后醒来的经过就读不到别的字符了.更加好的点子是先有一个进度读取一片段的字符,然后第三个进程被提醒,会意识那第3个经过还是能读到一些字符,而这么些字符是首先个进程读完剩余的.

3.Pump进程

3.率先条中的遗留难题,为何这二种处境有不一致的表现.

 
 pump进度运维在数据库源端,其作用是将源端发生的本土trail文件,把trail以数据块的款型通过TCP/IP
协商发送到指标端,那一般也是引入的方式。pump进度本质是extract进度的壹种卓殊方式,要是不行使trail文件,那么extract进度在抽取完数据之后,直接投递到指标端,生成远程trail文件.

  原因是:借使实进度先sleep,父进度读取完数据之后,父进度退出,此时写端s[0]的引用计数变为0(此前子进度已积极close了三次),被系统释放,依照read的语义,当子进度被提示后会读取到EOF;可是当大家先让父进度sleep的时候,子进度读取完后退出,由于写端在父进度,未有被放走,所以父进程此时不通在读操作上.

 
 与Pump进度对于的叫Server
Collector进度,这几个历程不供给引起我们的关心,因为在实操进度中,无需大家对其展开其余配置,所以对大家的话它是晶莹剔透的。它运转在指标端,其职责就是把Extract/Pump投递过来的数额再次组建成远程trail文件.

  用其它二个测试来验证,大家在子进度中不积极履行close[0],也等于有五个写端,然后别的不变,子进度先sleep,父进度先读取到数据
然后脱离,但此刻更凑巧有个分别,父进程退出的时候s[0]这么些写端的描述符并不会减到0,因为子进度中还装有二个引用,所以写端健在,子进程被晋升未来不会读到EOF再次来到,而是阻塞在读操作上

 
 pump进度能够在线大概批量配置,他得以展开多少过滤,映射和转换,同时他还足以布置为“直通形式”,那样数据被传输到对象端时就能够一向生成所需的格式,无需别的操作.
直通格局升高了data pump的频率,因为变化后的对象
不需求后续拓展检索.

 

 

最后,有关socketpair在基本中贯彻的一小点讲述:

在大部分景况下,oracle都建议选拔data
pump,原因如下:

socketpair会创制五个描述符,但改描述符不属于其余的莫过于文件系统,而是网络文件系统,虚拟的.同时内核会将这七个描述符互相设为本人的
peer即对端(那里即消除了如何标识读写端,可以想像,多少个描述符互为读写缓冲区,即消除了这些题材).然后选择相应socket家族里的
read/write函数执行读写操作.

 
 壹.为对象端或网络难题提供有限帮忙:若是只在目的端配置trail文件,由于源端会将extract进度抽取的始末不断的保留在内部存款和储蓄器中,并立时的发送到指标端。当互联网只怕指标端出现故障时,
由于extract进度不能马上的将数据发送到目的, extract进度将耗尽内部存款和储蓄器然后分外终止。 假若在源端配置了data
pump进程,捕获的多少会被撤换来硬盘上,预防了这几个终止的景观。当故障修复,源端和指标端
复苏连通性时,data pump进度发送源端的trail文件到指标端。

有了这么些基础,即可了解怎么试用fork发生的四个子进程都不倒闭读端的时候会竞争,如上所述,他们共享相同的文书表项,有雷同的inode和偏移量,五个进度的操作当然是相互影响的.

 
 二.方可支撑复杂的数目过滤或许转换
:当使用数据过滤恐怕更换时,能够先安插3个data
pump进度在目的端大概源端举办第壹步的转换,利用另叁个data pump进度只怕Replicat组实行第3部的转移。

 
 3.卓有功效的统一筹划存储能源 :当从几个数据源同步到多少个数据基本时,选拔data
pump的法子,能够在源端保存抽取的多寡,指标端保存trail文件,从而省去存款和储蓄空间。

 
 4.化解单数据源向多少个目的端传输数据的单点故障
:当从二个数据源发送数据到四个对象端时,能够为各类指标端独家铺排分歧的data
pump进程。那样一旦某些指标端失效可能网络故障时,其余的靶子端不会遭到震慑能够延续联合数据。

 

4.Replicat进程

 
 Replicat进度,称之为复制利用进度。运转在指标端,是多少传递的最后1站,负责读取指标端trail文件中的内容,并将其分析为DML或
DDL语句,然后使用到目的数据库中.和Extract进度一样,Replicat也有其里面包车型大巴checkpoint机制,保障重启后方可从上次记下的地方上马恢复而过多据损失的危害.

   Replicat
进度的图景包涵Stopped(经常甘休),Starting(正在起步),Running(正在运行),阿贝nded(Abnomal
End的缩写,标示万分截止)。 

 

5.Trail文件

   效能:存款和储蓄业务变化新闻(DDL和DML事务操作记录)

   主库上的trail文件是可选的

4858.com , 
 备库上的trail文件是必须的(因为Replicat进度必要读取该公文中的DDL或DML
SQL用来接纳)

 
 如若在主库上边定义了PUMP过程,那么就须求在主库上创制trail文件,因为PUMP进程将主库上的trail文件以块级别传输给网络上的从库。

发表评论

电子邮件地址不会被公开。 必填项已用*标注

网站地图xml地图
Copyright @ 2010-2019 美高梅手机版4858 版权所有