Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Począwszy od programu SQL Server 2019 (15.x) CU13, można skonfigurować replikację równorzędną w celu automatycznego rozwiązywania konfliktów, umożliwiając najnowsze wstawianie lub aktualizację w celu wygrania konfliktu. Jeśli dowolny zapis usunie wiersz, program SQL Server umożliwia usunięcie w celu wygrania konfliktu. Ta metoda jest znana jako ostatnia wygrana zapisu.
Użyj procedur składowanych, aby skonfigurować ostatnie zwycięstwa zapisu. Nie używaj Kreatora topologii równorzędnej do dodawania lub usuwania węzłów podczas korzystania z ostatniego składnika zapisywania.
Ważne zagadnienia dotyczące konfiguracji
Uwaga / Notatka
Po aktualizacji do programu SQL Server 2019 (15.x) CU13 lub nowszej wersji podczas konfigurowania publikacji z rozwiązaniem konfliktów ustawionym na ostatnie zwycięstwo zapisu dodatkowe metadane zostaną uwzględnione w publikacji. Jeśli później odinstalujesz/obniżysz wersję do wersji starszej niż AKTUALIZACJA CU13 programu SQL Server 2019 (15.x), te dodatkowe metadane powodują problemy. Przed obniżeniem poziomu należy usunąć wszystkie takie publikacje, a następnie utworzyć je ponownie w niższej wersji.
Podczas konfigurowania replikacji równorzędnej za pomocą automatycznego odnajdywania konfliktów i rozwiązywania problemów w celu rozwiązania ich jako ostatnich zwycięstw zapisu uwzględnij następujące konfiguracje i ustawienia:
Utwórz publikację przy użyciu następujących parametrów:
Ustaw
@p2p_conflictdetection_policy = 'lastwriter'wartość , aby określić ostatnią wygraną zapisu. Zobacz sp_addpublication (Transact-SQL). Ten parametr został wprowadzony w programie SQL Server 2019 (15.x) CU13. Wartośćoriginatoriddomyślna rozwiązuje konflikt na podstawie identyfikatora inicjatora i jest taka sama jak rozwiązywanie konfliktów przed programem SQL Server 2019 (15.x) CU13.Ustaw
@p2p_continue_onconflict = 'true'wartość , aby umożliwić agentowi dystrybucji rozwiązanie konfliktu.
Po dodaniu artykułu (
sp_addarticle) potwierdź zachowanie typu polecenia dla polecenia aktualizacji (@upd_cmd). Dostępne są następujące opcje:-
CALL(Ustawienie domyślne) SCALL
Zobacz szczegóły w sp_addarticle.
-
Jeśli dodasz artykuł (
sp_addarticle) w publikacji z zasadami wykrywania konfliktów ostatniego składnika zapisywania, użyjCALLpolecenia lubSCALLjako typ polecenia dla@upd_cmdparametru,CALLjest domyślny.Uwaga / Notatka
Program SQL Server obsługuje program
SCALLdla programu@upd_cmd. WSCALLprzypadku , gdy transakcja aktualizuje wartość do tej samej wartości, nie jest traktowana jako zmiana, aSCALLformat nie dostarcza wartości kolumn, które nie są aktualizowane ani modyfikowane. Aby uzyskać więcej informacji na temat formatu wywołania SCALL, zobacz Wywoływanie składni procedur składowanych.Publikacji równorzędnej można używać z wykrywaniem konfliktów ostatniego składnika zapisywania i rozwiązywaniem ich w grupie dostępności. Zobacz:
Możesz zobaczyć konflikt i jego rozwiązanie.
- W programie SQL Server Management Studio kliknij publikację prawym przyciskiem myszy i wybierz polecenie Wyświetl konflikty.
lub
- Wykonywanie zapytań
conflict_schemaname_tablenamedotyczących bazy danych publikacji. Na przykładconflict_dbo_tab1. Zobacz conflict_<schema>_<table> (Transact-SQL).
Konflikty wstawiania i aktualizacji są rozwiązywane na podstawie ostatniego składnika zapisywania, ale usuwanie zawsze zwycięża. Jeśli na przykład wystąpił konflikt usuwania aktualizacji i aktualizacja została wykonana w późniejszym czasie, usunięcie nadal wygrywa.
Wykrywanie i rozwiązywanie konfliktów ostatniego składnika zapisywania jest określane na podstawie ukrytej kolumny
$sys_mw_cd_id. Typ danych tej kolumny to data/godzina2.
Porównanie wykrywania konfliktów
W poniższej tabeli porównano, w jaki sposób konflikty są wykrywane i rozwiązywane przy użyciu tradycyjnej replikacji równorzędnej, a po włączeniu ostatniego rozwiązywania konfliktów składnika zapisywania:
| Typ konfliktu | Szczegóły konfliktu | Peer-to-peer | Ostatni zapis |
|---|---|---|---|
| Insert-Insert | Wszystkie wiersze w każdej tabeli uczestniczące w replikacji równorzędnej są jednoznacznie identyfikowane przy użyciu wartości klucza podstawowego. Konflikt wstawiania występuje, gdy wiersz o tej samej wartości klucza został wstawiony w więcej niż jednym węźle. | Jeśli wiersz przychodzący jest zwycięzcą, zaktualizujemy wiersz docelowy. W obu przypadkach rejestrujemy informacje. | Jeśli wiersz przychodzący jest zwycięzcą, zaktualizujemy wiersz docelowy. W obu przypadkach rejestrujemy informacje. |
| Update-Update | Występuje, gdy ten sam wiersz został zaktualizowany w więcej niż jednym węźle. | Jeśli wiersz przychodzący jest zwycięzcą, zmodyfikujemy tylko zmienione kolumny. | Jeśli wiersz przychodzący jest zwycięzcą, zmodyfikujemy wszystkie kolumny w miejscu docelowym (jeśli @upd_cmd ustawiono default wartość – CALL). |
| Update-Insert | Występuje, jeśli wiersz został zaktualizowany w jednym węźle, ale ten sam wiersz został usunięty, a następnie ponownie zainstalowany w innym węźle. | Jeśli wiersz przychodzący jest zwycięzcą, zmodyfikujemy tylko zmienione kolumny. | Dzieje się tak, gdy wiersz jest aktualizowany peer1 , a ten sam wiersz jest usuwany i ponownie wyświetlany w pliku peer2. Po zakończeniu synchronizacji wiersz jest peer1 usuwany jako usunięcie zawsze wygrywa, a następnie ten sam wiersz jest wstawiany, podczas gdy wiersz jest aktualizowany peer2 w miarę późniejszego aktualizowania. Prowadzi to do niekonwergencencji. |
| Wstaw — aktualizacja | Występuje, jeśli wiersz został usunięty, a następnie ponownie zainstalowany w jednym węźle, a ten sam wiersz został zaktualizowany w innym węźle. | Jeśli wiersz przychodzący jest zwycięzcą, zaktualizujemy wszystkie kolumny. | Dzieje się tak, gdy wiersz jest usuwany i ponownie wyświetlany, a ten sam wiersz jest aktualizowany peer1 w dniu peer2. Po zakończeniu synchronizacji wiersz jest usuwany peer2 jako usunięcie zawsze wygrywa, a następnie jest on wstawiany ponownie. W systemie peer1aktualizacja jest pomijana. |
| Delete-Insert Insert-Delete |
Występuje, jeśli wiersz został usunięty w jednym węźle, ale ten sam wiersz został usunięty, a następnie ponownie wyświetlony w innym węźle. | Obecnie uważamy to za konflikt D-U, a jeśli przychodzący wiersz jest zwycięzcą, usuwamy wiersz z miejsca docelowego. | Dzieje się tak, gdy wiersz jest usuwany, peer1 a ten sam wiersz jest usuwany i ponownie włączony .peer2 Po zakończeniu synchronizacji wiersz jest peer2 usuwany, podczas gdy wiersz jest wstawiany w pliku peer1. Dzieje się tak, ponieważ nie przechowujemy informacji o usuniętym wierszu, więc nie wiemy, czy wiersz został usunięty, czy nie był obecny w obiekcie równorzędnym. Prowadzi to do niekonwergencencji. |
| Delete-Update | Występuje, jeśli wiersz został usunięty w jednym węźle, ale ten sam wiersz został zaktualizowany w innym węźle. | Obecnie uważamy, że jest to konflikt D-U, a jeśli przychodzący wiersz jest zwycięzcą, usuwamy wiersz z miejsca docelowego. | Jest to konflikt D-U. Usunięcie zawsze wygrywa, usunięcie przychodzące jest zwycięzcą i usuwamy wiersz z miejsca docelowego. |
| Update-Delete | Występuje, jeśli wiersz został zaktualizowany w jednym węźle, ale ten sam wiersz został usunięty w innym węźle. | W procedurze składowanej aktualizacji równorzędnej komunikacji równorzędnej, jeśli występuje konflikt U-D, wyświetlimy następujący komunikat i nie rozwiążemy problemu.An update-delete conflict was detected and unresolved. The row could not be updated since the row does not exist. |
Jest to konflikt U-D. Jak usuwanie zawsze wygrywa, aktualizacja przychodząca jest pomijana. |
| Delete-Delete | Występuje, gdy wiersz został usunięty w więcej niż jednym węźle. | W procedurze składowanej peer-to-peer Usuń, jeśli występuje konflikt D-D, nie przetwarzamy żadnych zmian, po prostu je rejestrujemy. | Jeśli występuje konflikt D-D, to nie przetwarzamy żadnych zmian, po prostu je rejestrujemy. |
Uwaga / Notatka
W bieżącej implementacji zasad wykrywania konfliktów ostatniego modułu zapisywania usunięcie zawsze jest wygrywane, gdy występuje konflikt operacji insert-delete, delete-insert lub update-delete.
Przykłady
Tworzenie publikacji w pierwszej komunikacji równorzędnej (Node1)
W tym przykładzie skrypt:
- Publikuje bazę danych o nazwie
MWPubDB. - Nadaj publikacji
PublMWnazwę . - Konfiguruje zasady wykrywania konfliktów i rozwiązywania problemów podczas ostatniego zapisu wygrywa:
, @p2p_continue_onconflict= 'true', @p2p_conflictdetection_policy = 'lastwriter'
USE [MWPubDB];
EXECUTE sp_replicationdboption
@dbname = N'MWPubDB',
@optname = N'publish',
@value = N'true';
GO
-- Adding the transactional publication
USE [MWPubDB];
EXECUTE sp_addpublication
@publication = N'PublMW',
@description = N'Peer-to-Peer publication of database ''MWPubDB'' from Publisher ''Node1''.',
@sync_method = N'native',
@retention = 0,
@allow_push = N'true',
@allow_pull = N'true',
@allow_anonymous = N'false',
@enabled_for_internet = N'false',
@snapshot_in_defaultfolder = N'true',
@compress_snapshot = N'false',
@ftp_port = 21,
@allow_subscription_copy = N'false',
@add_to_active_directory = N'false',
@repl_freq = N'continuous',
@status = N'active',
@independent_agent = N'true',
@immediate_sync = N'true',
@allow_sync_tran = N'false',
@allow_queued_tran = N'false',
@allow_dts = N'false',
@replicate_ddl = 1,
@allow_initialize_from_backup = N'true',
@enabled_for_p2p = N'true',
@enabled_for_het_sub = N'false',
@p2p_conflictdetection = N'true',
@p2p_originator_id = 100,
@p2p_continue_onconflict = 'true',
@p2p_conflictdetection_policy = 'lastwriter';
GO
USE [MWPubDB];
EXECUTE sp_addarticle
@publication = N'PublMW',
@article = N'tab1',
@source_owner = N'dbo',
@source_object = N'tab1',
@type = N'logbased',
@description = NULL,
@creation_script = NULL,
@pre_creation_cmd = N'drop',
@schema_option = 0x0000000008035DDB,
@identityrangemanagementoption = N'manual',
@destination_table = N'tab1',
@destination_owner = N'dbo',
@status = 16,
@vertical_partition = N'false',
@ins_cmd = N'CALL sp_MSins_dbotab1',
@del_cmd = N'CALL sp_MSdel_dbotab1',
@upd_cmd = N'CALL sp_MSupd_dbotab1';
GO
Tworzenie publikacji na drugim elementach równorzędnych (Node2)
Poniższy skrypt tworzy publikację w drugim elementu równorzędnym (Node 2).
USE [MWPubDB];
EXECUTE sp_replicationdboption
@dbname = N'MWPubDB',
@optname = N'publish',
@value = N'true';
GO
-- Adding the transactional publication
USE [MWPubDB];
EXECUTE sp_addpublication
@publication = N'PublMW',
@description = N'Peer-to-Peer publication of database ''MWPubDB'' from Publisher ''Node2''.',
@sync_method = N'native',
@retention = 0,
@allow_push = N'true',
@allow_pull = N'true',
@allow_anonymous = N'false',
@enabled_for_internet = N'false',
@snapshot_in_defaultfolder = N'true',
@compress_snapshot = N'false',
@ftp_port = 21,
@allow_subscription_copy = N'false',
@add_to_active_directory = N'false',
@repl_freq = N'continuous',
@status = N'active',
@independent_agent = N'true',
@immediate_sync = N'true',
@allow_sync_tran = N'false',
@allow_queued_tran = N'false',
@allow_dts = N'false',
@replicate_ddl = 1,
@allow_initialize_from_backup = N'true',
@enabled_for_p2p = N'true',
@enabled_for_het_sub = N'false',
@p2p_conflictdetection = N'true',
@p2p_originator_id = 1,
@p2p_continue_onconflict = 'true',
@p2p_conflictdetection_policy = 'lastwriter';
GO
USE [MWPubDB];
EXECUTE sp_addarticle
@publication = N'PublMW',
@article = N'tab1',
@source_owner = N'dbo',
@source_object = N'tab1',
@type = N'logbased',
@description = NULL,
@creation_script = NULL,
@pre_creation_cmd = N'drop',
@schema_option = 0x0000000008035DDB,
@identityrangemanagementoption = N'manual',
@destination_table = N'tab1',
@destination_owner = N'dbo',
@status = 16,
@vertical_partition = N'false',
@ins_cmd = N'CALL sp_MSins_dbotab1',
@del_cmd = N'CALL sp_MSdel_dbotab1',
@upd_cmd = N'CALL sp_MSupd_dbotab1';
GO
Tworzenie subskrypcji z węzła Node1 do węzła Node2
USE [MWPubDB];
EXECUTE sp_addsubscription
@publication = N'PublMW',
@subscriber = N'Node2',
@destination_db = N'MWPubDB',
@subscription_type = N'Push',
@sync_type = N'replication support only',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0;
GO
EXECUTE sp_addpushsubscription_agent
@publication = N'PublMW',
@subscriber = N'Node2',
@subscriber_db = N'MWPubDB',
@job_login = NULL,
@job_password = NULL,
@subscriber_security_mode = 1,
@frequency_type = 64,
@frequency_interval = 1,
@frequency_relative_interval = 1,
@frequency_recurrence_factor = 0,
@frequency_subday = 4,
@frequency_subday_interval = 5,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@dts_package_location = N'Distributor';
GO
Tworzenie subskrypcji z węzła Node2 do węzła Node1
USE [MWPubDB];
EXECUTE sp_addsubscription
@publication = N'PublMW',
@subscriber = N'Node1',
@destination_db = N'MWPubDB',
@subscription_type = N'Push',
@sync_type = N'replication support only',
@article = N'all',
@update_mode = N'read only',
@subscriber_type = 0;
GO
EXECUTE sp_addpushsubscription_agent
@publication = N'PublMW',
@subscriber = N'Node1',
@subscriber_db = N'MWPubDB',
@job_login = NULL,
@job_password = NULL,
@subscriber_security_mode = 1,
@frequency_type = 64,
@frequency_interval = 1,
@frequency_relative_interval = 1,
@frequency_recurrence_factor = 0,
@frequency_subday = 4,
@frequency_subday_interval = 5,
@active_start_time_of_day = 0,
@active_end_time_of_day = 235959,
@active_start_date = 0,
@active_end_date = 0,
@dts_package_location = N'Distributor';
GO
Treści powiązane
- Komunikacja równorzędna — wykrywanie konfliktów w replikacji równorzędnej
- Artykuły transakcyjne — określanie sposobu propagacji zmian
- sp_addpublication (Transact-SQL)
- Konfigurowanie jednego elementu równorzędnego w ramach grupy dostępności
- Konfigurowanie obu elementów równorzędnych w grupach dostępności