2011-01-12 4 views
1

MySQL 데이터베이스를 사용하는 위치 A (LA-MySQL)에 응용 프로그램이 있습니다. 또한 PostgreSQL 데이터베이스를 사용하는 위치 B (LB-PSQL)의 또 다른 응용 프로그램입니다. (위치에 따라 물리적으로 먼 장소와 다른 네트워크가 중요한 경우)postgresql 데이터베이스와 mysql 데이터베이스의 데이터를 동기화하는 방법은 무엇입니까?

LA-MySQL과 동기화되도록 LB-PSQL에서 하나의 테이블을 업데이트해야하지만 정확히 어떤 것이이 모범 사례인지는 알 수 없습니다 지역.

또한 LB-PSQL에서 업데이트해야하는 테이블은 반드시 LA-MySQL과 동일한 구조를 가지고 있지 않습니다. (하지만 LB-PSQL에서 업데이트해야하는 필드가 LA-MySQL 필드의 데이터를 수용 할 수 있으므로 문제가되지 않는다고 생각합니다.)

이 데이터는 모범 사례, 일반적인 방법 또는 이런 종류의 일을하기위한 참조?

피드백에 대해 미리 감사드립니다.

+0

동기 (느린 것, 마스터 커밋의 순간에 복제본에 보이는 변경) 또는 비동기식 (빠른 것이지만 약간의 지연 후에 복제본의 변경 사항을 볼 수 있음)이 필요합니까? 비동기라면 어떤 종류의 지연이 생길 수 있습니다 : 몇 초, 몇 시간, 하루입니까? – Tometzky

+0

@Tometzky, 완벽하게 비동기적인 작업이 될 수 있습니다. 지연에 관해서는, 나는 하루/일 사이에 무언가와 함께 살 수 있습니다. – acm

답변

2

두 서버가 서로 다른 네트워크에있는 경우 데이터를 MySQL에서 플랫 파일로 내보내는 것이 유일한 방법입니다.

그런 다음 PostgreSQL 서버에 파일 (비슷한 예를 들어, FTP 또는 무언가)를 전송하고 그것이 내가 준비 테이블에 플랫 파일을 가져 추천 할 것입니다 COPY

사용이 가져옵니다. 여기에서 SQL을 사용하여 적절한 대상 테이블로 데이터를 이동할 수 있습니다. 그러면 데이터 변환을 수행하거나 기존 행에 대한 업데이트를 수행 할 수 있습니다.

변환이 더 복잡한 경우 ETL 도구 (예 : 주전자)를 사용하여 대상 서버에서 이전 작업을 수행하는 것이 좋습니다.

+0

감사하지만, "자동화 된 프로세스"솔루션의 일종, 수출, FTP를 통한 전송 및 가져 오기가 이상적이지는 않습니다. – acm

+1

일부 전선을 넣지 않고도 100 % 자동화 된 프로세스가 없습니다. 뭔가해야 할 일이 있습니다. 이러한 유형의 작업을 위해 설계 되었기 때문에 ETL 도구 (Pentaho 어쩌면)를 볼 수는 있지만 ETL 프로세스를 만들려면 몇 가지 개발 작업이 필요합니다. – Kuberchaun

1

그냥이 (bash는 샘플) 같은 것을 할 것 LA에서 스크립트 작성 :

TMPFILE=`mktemp` || (echo "mktemp failed" 1>&2; exit 1) 
pg_dump --column-inserts --data-only --no-password \ 
    --host="LB_hostname" --username="username" \ 
    --table="tablename" "databasename" \ 
    awk '/^INSERT/ {i=1} {if(i) print} # ignore everything to first INSERT' \ 
    > "$TMPFILE" \ 
    || (echo "pg_dump failed" 1>&2; exit 1) 
(echo "begin; truncate tablename;"; cat "$TMPFILE"; echo 'commit;') \ 
    | mysql "databasename" < "$TMPFILE" \ 
    || (echo "mysql failed" 1>&2; exit 1) \ 
rm "$TMPFILE" 

을 그리고 크론에 하루에 한 번, 예를 들어 실행되도록 설정합니다. postgresql 암호에는 '.pgpass'가 필요하고, mysql 암호에는 mysql 옵션 파일이 필요합니다.

이것은 100 만 개 미만의 행에 대해 충분히 빠릅니다.

+0

awk를 제발 같이 설명해 주시겠습니까? – DrColossos

+0

코멘트가 있습니다 - "처음 INSERT 할 때 모든 것을 무시하십시오". pg_dump는 다른 데이터베이스와 호환되지 않는 구성 라인을 생성합니다 -이 awk는 "INSERT"로 시작하는 라인이 나타날 때까지 모든 것을 무시합니다. – Tometzky

+0

나는 코멘트를 읽었습니다;) 왜 ("pg_dump는 [...]에 대한 몇 줄을 생성합니까?") 더 관심이있었습니다. – DrColossos

0

턴키 솔루션이 아니지만 트리거를 사용하여이 작업을 돕는 코드입니다. 다음은 간결함을위한 삭제 또는 갱신을 전제로하지 않습니다. 필요 PG> = 9.1

1) 새 테이블을 2 개 준비하십시오. mytable_a 및 mytable_b. 소스 테이블과 같은 열이 복제되는 :

-- move data from mytable_a -> mytable_b without stopping trigger 
WITH d_rows AS (DELETE FROM mytable_a RETURNING *) INSERT INTO mytable_b SELECT * FROM d_rows; 

-- export data from mytable_b -> file 
\copy mytable_b to '/tmp/data.csv' WITH DELIMITER ',' csv; 

-- empty table 
TRUNCATE mytable_b; 

이 그럼 당신은 MySQL의에 data.csv를 가져올 수 있습니다

CREATE TABLE mytable_a AS TABLE mytable WITH NO DATA; 
CREATE TABLE mytable_b AS TABLE mytable WITH NO DATA; 

-- trigger function which copies data from mytable to mytable_a on each insert 
CREATE OR REPLACE FUNCTION data_copy_a() RETURNS trigger AS $data_copy_a$ 
    BEGIN 
    INSERT INTO mytable_a SELECT NEW.*; 
     RETURN NEW; 
    END; 
$data_copy_a$ LANGUAGE plpgsql; 

-- start trigger 
CREATE TRIGGER data_copy_a AFTER INSERT ON mytable FOR EACH ROW EXECUTE PROCEDURE data_copy_a(); 

그런 다음 내보낼 필요로 할 때.

관련 문제