Tạo trình kích hoạt để cập nhật dữ liệu bảng trên cơ sở dữ liệu của Máy chủ khác


8

Tôi đang tạo một kích hoạt trong MySQL và tôi cần một chút giúp đỡ.

Tôi có 2 trang web, 2 cơ sở dữ liệu (cùng tên) trên 2 máy chủ web khác nhau, S1 & S2.

Các cơ sở dữ liệu này có cùng tên bảng.

Tôi muốn cả dữ liệu người dùng trên cả hai trang web đều giống nhau.

Vì vậy, nếu một người dùng đăng ký trên S1, thì thông tin đăng ký người dùng đó sẽ được chuyển đến S2.

Nếu thông tin đăng ký người dùng được cập nhật trên S1, thông tin tương tự sẽ được cập nhật trên S2.

Và điều tương tự áp dụng cho S2.

Làm cách nào tôi có thể tạo trình kích hoạt để mỗi lần có chèn / cập nhật / xóa trong cơ sở dữ liệu trên S1, thì bảng người dùng trên S2 cũng được cập nhật tự động.

Và mỗi khi có chèn / cập nhật / xóa trong cơ sở dữ liệu trên S2, thì bảng người dùng trên S1 cũng được cập nhật tự động.

Điều này có thể không? Bạn có thể cung cấp một số ví dụ?


Tôi nghĩ rằng bạn đang theo một kiểu sao chép nào đó, không phải là trình kích hoạt - theo hiểu biết của tôi thì cái sau chỉ hoạt động trong cùng một thể hiện MySQL, nghĩa là có thể định nghĩa các kích hoạt ảnh hưởng đến nhiều hơn một cơ sở dữ liệu nhưng chúng phải nằm trên cùng một cơ sở dữ liệu người phục vụ.
dezso

Ok Cảm ơn dezso. Có cách nào khác để tôi có thể làm như trên trong MySQL không?
mkb

1
Ngoài ra - hãy cẩn thận. Loại cập nhật này chỉ được thực hiện tốt nhất với một cái gì đó được tách rời, nếu không máy chủ thứ hai trở xuống sẽ giết các bản cập nhật trên cơ sở dữ liệu đầu tiên.
TomTom

Câu trả lời:


11

Để thực hiện những gì bạn muốn làm, có thể sử dụng FEDERATEDcông cụ lưu trữ trên cả hai máy chủ, kết hợp với trình kích hoạt, để cho phép mỗi máy chủ cập nhật cơ sở dữ liệu của máy chủ khác.

Đây không chính xác là một giải pháp bên ngoài đơn giản, bởi vì nó yêu cầu các biện pháp phòng ngừa bổ sung và yêu cầu bạn quyết định xem tính nhất quán hay dung sai cách ly là quan trọng hơn và cho phép các truy vấn thất bại khi máy chủ khác không khả dụng (tính nhất quán cao hơn ) hoặc sử dụng a CONTINUE HANDLERđể triệt tiêu lỗi (dung sai cách ly).

Nhưng đây là một ví dụ cực kỳ đơn giản.

Mỗi máy chủ sẽ có cấu hình giống hệt nhau.

Bảng người dùng cục bộ:

CREATE TABLE user (
  username varchar(64) NOT NULL,
  password varbinary(48) NOT NULL, /* encrypted of course */
  PRIMARY KEY(username)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;

Một bảng cục bộ được liên kết với bảng người dùng trên máy chủ khác.

CREATE TABLE remote_user (
  username varchar(64) NOT NULL,
  password varbinary(48) NOT NULL, /* encrypted of course */
  PRIMARY KEY(username)
) ENGINE=FEDERATED DEFAULT CHARSET=utf8 CONNECTION='mysql://username:pass@the_other_host:port/schema/user';

Chọn từ remote_user trên một máy chủ sẽ truy xuất các bản ghi từ máy chủ khác và chèn / cập nhật / xóa trên bảng đó sẽ thay đổi dữ liệu trên máy chủ khác.

Vì vậy, chúng tôi tạo ra các kích hoạt thực hiện mục đích cập nhật máy chủ khoảng cách. Chúng được viết dưới dạng BEFOREkích hoạt, với ý tưởng là chúng ta không muốn làm gì đó với chính mình mà chúng ta không thể làm với máy chủ khác - ví dụ: nếu tên người dùng đã tồn tại trên máy chủ khác, nhưng không phải ở đây, chúng tôi muốn chèn vào máy chủ khác để đưa ra lỗi ngăn chúng tôi tạo người dùng ở đây ... trái ngược với việc tạo người dùng ở đây với tên người dùng mâu thuẫn. Tất nhiên, đây là một trong những quyết định đánh đổi mà bạn cần đưa ra.

DELIMITER $$

CREATE TRIGGER user_bi BEFORE INSERT ON user FOR EACH ROW
BEGIN
  INSERT INTO remote_user (username,password) VALUES (NEW.username,NEW.password);
END $$

CREATE TRIGGER user_bu BEFORE UPDATE ON user FOR EACH ROW
BEGIN
  UPDATE remote_user 
     SET username = NEW.username,
         password = NEW.password
   WHERE username = OLD.username;
END $$

CREATE TRIGGER user_bd BEFORE DELETE ON user FOR EACH ROW
BEGIN
  DELETE FROM remote_user
   WHERE username = OLD.username;
END $$

DELIMITER ;

Đây không phải là một giải pháp hoàn hảo và không phải là một giải pháp có tính sẵn sàng cao, bởi vì nó phụ thuộc vào kết nối chắc chắn giữa hai hệ thống và ngay cả khi bạn đang sử dụng InnoDB và các giao dịch, các hành động bạn thực hiện đối với bảng mục tiêu không phải là một phần của giao dịch cục bộ của bạn và không thể quay trở lại.

Tôi sử dụng FEDERATEDđộng cơ khá nhiều; nó có ích cho một số mục đích sáng tạo trong môi trường của tôi, bao gồm một tình huống trong đó tôi đã sử dụng truy vấn được liên kết do trình kích hoạt đưa ra để áp đặt các ràng buộc khóa ngoài đối với nguồn dữ liệu nước ngoài; tuy nhiên, tôi hạn chế sử dụng nó cho các quy trình back-end trong đó các sự cố không mong muốn như hết thời gian, lỗi mã hóa hoặc các sự kiện cách ly / ngắt mạng / máy chủ đến máy chủ không thể dẫn đến việc người dùng cuối trên một trong các trang web của chúng tôi gặp phải bất kỳ sự cố nào . Khả năng của bạn để chịu đựng một tình huống như vậy sẽ là một yếu tố quyết định chính vào việc liệu đây có phải là một giải pháp thích hợp.

Một cách khác là cấu hình hai máy chủ của bạn theo bản sao chính / chính. Đối với điều này, bạn sẽ cần sử dụng các tên cơ sở dữ liệu khác nhau trên mỗi máy chủ, do đó, đối với hầu hết các sự kiện sao chép, hai máy chủ không thể xung đột với nhau. Trong trường hợp xấu nhất, nếu bạn mất kết nối hoặc gặp lỗi sao chép, hai trang web vẫn sẽ hoạt động độc lập và bạn có thể đồng bộ hóa và khôi phục. Cấu hình sẽ trông giống như thế này:

database_a database for site A
database_b database for site B
database_c database for only the shared table(s)

Sau đó, trong cơ sở dữ liệu_a và cơ sở dữ liệu_b:

CREATE ALGORITHM=MERGE SQL SECURITY INVOKER VIEW user AS SELECT * FROM c.user;

MySQL sẽ coi cơ sở dữ liệu_a.user và cơ sở dữ liệu_b.user là bí danh cho bảng người dùng "thực", cơ sở dữ liệu_cuser, do đó bạn sẽ không phải thay đổi ứng dụng của mình ngoài việc sử dụng cơ sở dữ liệu được chỉ định của nó (nghĩa là bạn sẽ không phải định cấu hình để hiểu rằng bảng người dùng thực sự nằm trong một lược đồ khác, bởi vì khung nhìn sẽ hoạt động khá rõ ràng với cấu hình này). Nếu các lược đồ có khóa ngoại đối với bảng người dùng, bạn sẽ khai báo chúng dựa trên cơ sở dữ liệu bảng cơ sở thực sự_c.user.

Định cấu hình hai máy chủ để sao chép mọi thứ, nhưng đặt auto_increment_incrementauto_increment_offsetthích hợp để bạn không có các giá trị tăng tự động xung đột trên (các) bảng được chia sẻ, nếu các bảng của bạn sử dụng tự động tăng. (Lưu ý, tài liệu nói rằng các biến này chỉ dành cho NDBbảng, nhưng điều đó không chính xác).

Một lợi thế nữa của thiết lập này là hai máy chủ của bạn sau đó sẽ có một bản sao hoàn chỉnh của dữ liệu của trang web khác mà bạn có thể sử dụng để tạo lợi thế cho việc phục hồi từ lỗi phần cứng ở một trong các máy chủ.


1

Đó chỉ là một bảng trong số nhiều bảng bằng nhau, phải không?

Vì vậy, các kích hoạt sẽ không hoạt động vì chúng chỉ có thể được thực thi trong cùng một lược đồ trên cùng một máy chủ.

Đoán bạn có 3 lựa chọn:

  1. Đồng bộ hóa thủ công, ví dụ: bằng cách gọi một tập lệnh thực thi tất cả các truy vấn được thực hiện trên dữ liệu người dùng trên S1 trên máy chủ khác. Kinda xấu xí.

  2. Hướng tất cả các truy vấn trên bảng này đến một máy chủ, ví dụ S1 chứa ứng dụng có thể sử dụng được và ứng dụng của bạn, dù đó là gì, trên máy chủ 2 không truy vấn khả năng sử dụng cục bộ trên S2, nhưng từ xa trên S1. Không phải là tốt hơn.

  3. Sử dụng công cụ LIÊN KẾT. Lưu trữ dữ liệu người dùng trên S1, tạo cấu trúc bảng tương tự với FedERATED trên S2. Điều này có nghĩa, S2 không giữ dữ liệu người dùng vật lý mà kết nối với bảng trên S1. Tất cả các hành động được thực hiện trên S2 được thực hiện trên S1. Xem http://en.wikipedia.org/wiki/MyQuery_Federatedhttp://dev.mysql.com/doc/refman/5.0/en/federated-st Storage-engine.html để tìm hiểu xem điều này có phù hợp với nhu cầu của bạn không.

Trong cả 3 kịch bản, thật khó để đưa ra tuyên bố về độ trễ giữa các đồng bộ. Tùy chọn 3 là lựa chọn duy nhất mà bạn chỉ cần điều chỉnh cơ sở dữ liệu, không phải ứng dụng, nhưng tôi thực sự không biết liệu đó có phải là vấn đề lớn không.


0

Đầu tiên là một cảnh báo nhanh - id có thể đi theo lộ trình của các câu trả lời khác và sử dụng liên kết cho thiết lập cụ thể của bạn. Điều đó nói rằng đáng để bạn suy nghĩ một chút về việc liệu việc chia dữ liệu người dùng ra một db thứ ba có phải là một giải pháp tốt hơn không.

Nó sẽ xóa trùng lặp khỏi 2 dbs nhưng tôi dự đoán rằng nó cũng sẽ cần một số lượng lớn việc làm lại để có được 2 trang web hoạt động từ một db xác thực trung tâm


-1

Tạo một máy chủ được liên kết giữa các máy chủ của bạn và tạo một quy trình được lưu trữ trên cả hai máy chủ.

Thí dụ:

CREATE proc p_insert(your parameters)

...your logic

INSERT INTO table values ()
INSERT INTO [AnotherSERVERNAME].[DATABASE NAME].dbo.[Table] values()

Nó có thể giải quyết vấn đề của bạn.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.