Синхронизация 2 таблиц на сервере SQL - PullRequest
3 голосов
/ 03 ноября 2011

У меня есть таблица на сервере A и такая же таблица на другом сервере B. Я хочу обновлять таблицу на сервере A данными с сервера B один раз в день.Таблица на сервере A содержит более 100 миллионов записей.Как это сделать, чтобы при обновлении данных в таблице на сервере A они все еще были доступны для чтения с предыдущей информацией.

Предполагаемое поведение:

Сервер A:

create table tbl_transaction_test (
    tabid int identity,
    first_name nvarchar(255),
    last_name nvarchar(255),
    [address] nvarchar(255),
    update_dt datetime
)

Сервер B:

create table tbl_transaction_test (
    tabid int identity,
    first_name nvarchar(255),
    last_name nvarchar(255),
    [address] nvarchar(255),
    update_dt datetime
)

begin transaction transaction1
truncate table A
Insert into A.tbl_transaction_test 
     select * from B.tbl_transaction_test 
commit transaction transaction1

И в то же время я хочу выбрать из таблицы на сервере A.

Как я могу получить поведение, что данныев таблице на сервере A изменяется только когда транзакция совершается, и это делается мгновенно (почти мгновенно).

Ответы [ 3 ]

2 голосов
/ 03 ноября 2011

Может быть, вам стоит начать со статьи Обзор решений высокой доступности , если вы хотите встроенную функциональность.Обратите внимание, что для использования этих функций у вас должны быть соответствующие привилегии на обоих серверах.Вкратце:

  • Репликация - синхронизирует исходную и целевую базы данных с помощью
  • Доставка журналов - отправляет резервные копии журналов транзакций из одной базы данных/ server к одной или нескольким базам данных / серверам и применяет их к целевым базам данных
  • Зеркальное отображение - в основном он отправляет поток активных записей журнала транзакций на конечный сервер и применяет его к целевой базе данных

Не забудьте проверить, поддерживают ли ваши выпуски и лицензии SQL Server репликацию / зеркалирование / доставку журналов (или отказоустойчивость кластера, упомянутую в статье, если вы решите использовать ее).

илиВы можете создать собственное решение (похожее на репликацию) с триггером в исходной таблице:

  1. Триггер сохранит измененные записи в таблице журнала со столбцом отметки времени и статусом (обновлен, вставлен, удален).
  2. Скопируйте эту отдельную таблицу на целевой сервер, где отметка времени> last_timestamp_you_transfered в заданный интервал времени (используетсязадание)
  3. Применить изменения к целевому серверу (изменения, где отметка времени> last_timestamp_applied)

Примечания:

  • Вы всегда можете хранить небольшие таблицы, удаляя записи, гдеотметка времени меньше последней обработанной
  • Вы можете избежать задания, написав приложение, которое будет выполнять передачу каждые x секунд / минут

Каждое предлагаемое решение требует определенных разрешений на этих серверах.Либо Вам нужны разрешения для настройки репликации, зеркалирования, доставки журналов или создания триггеров + задания.

2 голосов
/ 03 ноября 2011

Andomar уже предложил, как сделать весь новый набор данных видимым «сразу», используя промежуточную таблицу и хороший трюк «ole» sp_rename. Существуют вариации на эту тему, как, например, использование многораздельной таблицы и отключение существующих данных, затем переключение в промежуточную таблицу, см. Эффективная передача данных с помощью переключения разделов .

Другой подход заключается в использовании изоляции моментальных снимков. С изоляцией моментального снимка вы можете удалить все строки в таблице и вставить новые в транзакцию, и это не заблокирует никаких читателей, так как все читатели будут продолжать использовать старые версии строк. См. Общие сведения об уровнях изоляции на основе версий строк .

Но нужно подвергнуть сомнению разумность схемы, предусматривающей перевод 100 миллионов в день. Это просто невозможно Так что идея манипулировать 100M строками в одной транзакции, наиболее вероятным результатом будет то, что ваш файл журнала транзакций будет расти, пока они не заполнят весь диск, а затем сервер перевернется и умрет.

Скорее всего, вам нужно одно из решений, предложенных Filip: репликация, зеркалирование или доставка журналов. Хорошим сравнением этих решений является техническая документация High Availability с SQL Server 2008 .

1 голос
/ 03 ноября 2011

Один из способов - использовать промежуточный стол. Вы копируете всю исходную таблицу в новую таблицу, а когда копирование завершено, вы удаляете старую таблицу и переименовываете промежуточную таблицу.

select  * 
into    A.tbl_transaction_test_staging
from    B.tbl_transaction_test

begin transaction
drop A.tbl_transaction_test
exec sp_rename 'A.tbl_transaction_test_staging', 'A.tbl_transaction_test'
commit transaction

Операция переименования выполняется довольно быстро.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...