Вверх ↑
Этот топик читают: Гость
Ответов: 655
Рейтинг: 18
#1: 2015-03-07 03:07:17 ЛС | профиль | цитата
Дано:

три БД, на разных 3хПК, связь между ПК не стабильная.

Во всех трех БД есть одна идентичная таблица, допустим:

test
id(int),data1(text),data2(text).

ПК1 "Главный" первоначально все записи создаются на нем. Когда подключаются ПК2 и ПК3 они получают одинаковые данные, допустим:

1;text;text
2;text;text

На трех ПК получается одинаковые БД.

Тут потребовалось сделать чтобы ПК2 и ПК3 тоже могли добавлять данные в свои БД и делится ими с ПК1.

Теперь ситуация:

ПК1 создал запись в БД:

последняя запись во всех 3х БД:

2;text;text

На ПК1 создается запись 3;data;data - ПК2 ее получил, ПК3 нет.

На ПК3 создается запись 3;text;text;

В результате в 1й из 3х БД данные не верные...а требуется чтобы данные были идентичны.

Пока вижу такой вариант:

Присвоить каждому ПК его ID, и добавить в таблицу столбец 'pcid', создать таблицы job_list_pc2 и job_list_pc3 в них хранить данные которые нужно "синхронизировать" между ПК1 ПК2 и ПК3. Что скажете? Есть какие либо камни подводные?





карма: 0

0
Ответов: 16884
Рейтинг: 1239
#2: 2015-03-07 09:18:18 ЛС | профиль | цитата
Синхронизация данных в трех БД
Какая разница - в двух, трёх или десяти ?
Ты хочешь чтобы любая запись, внесённая в одну БД, должна быть скопирована во все остальные.
Правильно ?
Gunnman писал(а):
Есть какие либо камни подводные?
Море.
Самая сложная проблема с полем id.
Дешевле зарезервировать линии связи с обеих сторон.
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 186
Рейтинг: 9
#3: 2015-03-07 19:59:28 ЛС | профиль | цитата
Gunnman, может обойтись одной БД типа mysql, чем городить огород?
карма: 0

0
Гость
Ответов: 17029
Рейтинг: 0
#4: 2015-03-07 20:18:01 правка | ЛС | профиль | цитата


Редактировалось 2 раз(а), последний 2025-01-10 09:46:04
карма: 0

0
Ответов: 186
Рейтинг: 9
#5: 2015-03-07 20:59:52 ЛС | профиль | цитата
По описанию задачи, нужна сетевая база данных.

Вы обязательно будите сталкиваться с тем что базы не досинхронизированы по причине не работы какого то из ПК.

109.235.188.9 писал(а):
1) ПК2 и ПК3 должны выполнять свою работу независимо от подключения к ПК1, в варианте с использование одного сервера mysql на ПК1 получается нет связи - ПК2 и ПК3 не могут выполнять свою работу.


Понятно что для этого понадобится ПК0, который будет сервером, кстати это может быть ПК1, или вообще host в интернете. Ну или хочешь работать обязательно включи ПК1.
У нас 1 рабочий компьютер, 2-х ядерный, так 2 года работал вообще без выключения пока сервак не купили, и ничего до сих пор жив.

109.235.188.9 писал(а):
2) функции шифрования в mysql не удобные, каждый раз указывать encryptdecrypt при чтениизаписи нужных полей.

Ну это же не проблема, если так должен строиться запрос.
Я ничего вообще в базе не шифрую, держу как есть.

Tad писал(а):
Море.

Я бы обратил внимание на это мнение.

В свое время мне пришлось переписать все запросы в моем приложении с SQLite на Mysql, какраз из за появления дополнительных ПК.

109.235.188.9 писал(а):
п.с. в качестве стабильного решения для серьезной задачи я бы рассматривал Oracle Linux, а пока мне хватает SQLite.

Кстати mysql делает именно Oracle.
https://ru.wikipedia.org/wiki/MySQL


карма: 0

0
Ответов: 16884
Рейтинг: 1239
#6: 2015-03-07 22:19:37 ЛС | профиль | цитата
Решил поработать писателем...
A. По умолчанию, SQLite собран с поддержкой потоков (sqlite3.dll).
Есть два способа использования многопоточного SQLite: serialized и multi-thread.
1. Serialized (надо указать флаг SQLITE_OPEN_FULLMUTEX при открытии соединения). В этом режиме потоки могут как угодно дергать вызовы SQLite, никаких ограничений. Но все вызовы блокируют друг друга и обрабатываются строго последовательно.
2. Multi-thread (SQLITE_OPEN_NOMUTEX). В этом режиме нельзя использовать одно и то же cоединение одновременно из нескольких потоков (но допускается одновременное использование разных соединений разными потоками). Обычно используется именно этот режим.

B. Если в вызове sqlite3_open() передать имя файла как ":memory:", то SQLite создаст соединение к новой (чистой) БД в памяти.
C. В любой момент времени мы можем к открытому соединению присоединить еще до 10 баз данных через SQL команду ATTACH DATABASE.
D. Если передать пустую строку вместо имени файла в sqlite3_open(), то будет создана временная БД в файле на диске. Причем, после закрытия соединения к БД, она будет удалена с диска.

Управление работой :
PRAGMA page_size = bytes; // размер страницы БД; страница БД - это единица обмена между диском и кэшом, разумно сделать равным размеру кластера диска (у меня 4096)
PRAGMA cache_size = XXXX; // задать размер кэша соединения в килобайтах, по умолчанию он равен 2000 страниц БД
PRAGMA encoding = "UTF-8"; // тип данных БД, всегда используйте UTF-8
PRAGMA foreign_keys = 1; // включить поддержку foreign keys, по умолчанию - ОТКЛЮЧЕНА
PRAGMA journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF; // задать тип журнала
PRAGMA synchronous = 0 | OFF | 1 | NORMAL | 2 | FULL; // тип синхронизации транзакции

Пределы
Несмотря на миниатюрность, SQLite в реальности не накладывает серьезных ограничений на размеры полей, таблиц или БД.
a) По умолчанию, BLOB или строкое значение могут занимать 1 Гбайт и это же ограничение размера одной записи (можно поднять до 2^31 — 1, параметр SQLITE_MAX_LENGTH).
b)Количество столбцов: 2000 (можно поднять до 32767, SQLITE_MAX_COLUMN).
c)Размер SQL оператора: 1 МБайт (1073741824 байт, SQLITE_MAX_SQL_LENGTH).
d)Одновременный join: 64 таблицы.
e)Присоединить баз к соединению: 10 (до 62, SQLITE_MAX_ATTACHED)
f)Максимальное количество страниц в БД: 1073741823 (до 2147483646, SQLITE_MAX_PAGE_COUNT).
g)Если задать размер страницы 65636 байт, то максимальный размер БД будет примерно 14 Терабайт.
h)Максимальное число записей в таблице: 2^64 — 1, но на практике, конечно, ограничение размера вступит раньше.

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 655
Рейтинг: 18
#7: 2015-03-07 22:50:21 ЛС | профиль | цитата
Chipset, Вы невнимательно прочитали)

ПК1 "Главный", он и есть по сути сервер, ни каких ПК0 тут не нужно.

п.с. ПК1 VDS с uptime хостера 99.8%.

Выбор MySql или другая БД - дело вкуса, они все выполняют свои задачи.

Функции шифрования в MySQL мне лично не нравятся, SQLite тот же шифрует всю базу а не отдельное полестроку.
п.с. Не использовать шифрование данные в моем случае нельзя, данные конечно не первой категории, но все же, шифрование нужно потому что ПК2 и ПК3 ноутбуки их могут потерятьукрасть.

Собственно к делу:

ПК1 условно доступен всегда, ПК2 и ПК3 не всегда имеют доступ к ПК1, между собой ПК2 и ПК3 никогда не имеют связи.

ПК1, ПК2, ПК3 создают записи в одинаковых таблицах.

ПК2 и ПК3 отсылают свои данные на ПК1, тот в свою очередь должен записать их к себе и:

- отправить свои записи и записи ПК3 на ПК2,
- отправить свои записи и записи ПК2 на ПК3.

Алгоритм прорабатываю отпишусь позже.






------------ Дoбавленo в 22.50:
Tad, По этой причине я и собрал обновленную библиотеку, переделал стандартные компоненты Sqlite для работы с интерфейсом _v2 за что Вам и Netspirit большое спасибо)
карма: 0

0
Ответов: 16884
Рейтинг: 1239
#8: 2015-03-07 23:33:43 ЛС | профиль | цитата
Gunnman, специально для тебя работал писателем выше
Multi-thread (SQLITE_OPEN_NOMUTEX). В этом режиме нельзя использовать одно и то же соединение одновременно из нескольких потоков (но допускается одновременное использование разных соединений разными потоками). Обычно используется именно этот режим.
т.е. все твои игры с sqlite_open_v2() - просто потраченное время, т.к. sqlite_open() по умолчанию открывыет файл БД именно в режиме SQLITE_OPEN_NOMUTEX.
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 655
Рейтинг: 18
#9: 2015-03-07 23:41:47 ЛС | профиль | цитата
Tad,

1) SQLITE открывате БД в том режиме который был указан при компиляции это написано на сайте sqlite. http://www.sqlite.org/threadsafe.html
The threading mode can be selected at compile-time (when the SQLite library is being compiled from source code) or at start-time (when the application that intends to use SQLite is initializing) or at run-time (when a new SQLite database connection is being created). Generally speaking, run-time overrides start-time and start-time overrides compile-time. Except, single-thread mode cannot be overridden once selected.


2) Режим по умолчанию SERIALIZED (SQLITE_THREADSAFE=1) http://www.sqlite.org/threadsafe.html
The default mode is serialized.


3) SQLITE открывает БД в режиме FULLMUTEX или NOMUTEX программно только через SQLITE3_OPEN_V2
пруф:
[url]https://www.sqlite.org/c3ref/open.html [/url]
https://www.sqlite.org/c3ref/c_open_autoproxy.html


карма: 0

0
Ответов: 16884
Рейтинг: 1239
#10: 2015-03-07 23:48:47 ЛС | профиль | цитата
Открой БД
Выполни команду PRAGMA threads;
Посмотри что она тебе вернёт.

карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 655
Рейтинг: 18
#11: 2015-03-07 23:57:00 ЛС | профиль | цитата
Tad, я все провел раз 10 уже) мои труды (для меня) прошли не напрасно, я научился собирать данную библиотеку, немного разобрался с тем как редактировать компоненты под свои нужны, главное - моя библиотека поддерживает шифрование и режимы работы которые мне нужны.

Так что..как бы удивительно это не звучало для форумчан Tad вы не правы
------------ Дoбавленo в 23.56:
PRAGMA threads; - ни чего не выдает

вот проверка!
https://www.sqlite.org/c3ref/threadsafe.html

через Delphi пока не разобрался как в компоненте добавить проверку ThreadSafe, проверял через скриптовый язык FBSL:

If sqlite3_threadsafe() > 0 Then
? "Library is threadsafe"
Else
? "Library is not threadsafe"
Exit Sub
End If
карма: 0

0
Ответов: 16884
Рейтинг: 1239
#12: 2015-03-08 00:24:28 ЛС | профиль | цитата
PRAGMA threads; стандартный SQLite_open возвращает 0.
На вопрос ответь пож.
Tad писал(а):
Выполни команду PRAGMA threads;
Посмотри что она тебе вернёт.

------------ Дoбавленo в 00.13:
через Delphi пока не разобрался как в компоненте добавить проверку
Add(Debug,1587977,490,707)
{
}
Add(DSC_Query,6294101,427,707)
{
SQL="PRAGMA threads;
"
link(onQuery,1587977:doEvent,[])
}
------------ Дoбавленo в 00.24:
Gunnman писал(а):
проверял через скриптовый язык FBSL:

Результат ?
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Ответов: 655
Рейтинг: 18
#13: 2015-03-08 02:28:29 ЛС | профиль | цитата
Tad, ни чего не возвращает, этой функции кажись нет в sqlite3.api))
------------ Дoбавленo в 00.27:
Gunnman писал(а):
Gunnman писал(а)
проверял через скриптовый язык FBSL:

Результат ?
"Library is threadsafe"

Сейчас выложу схемы для теста
------------ Дoбавленo в 01.46:
Вот Архив http://forum.hiasm.com/forum_serv.php?q=56&id=3916

В Архиве Pas исходники компонентов редактированные мной.

При FULLMUTEX БД открыта в 1 потоке, 5 других потоков пишут в нее (1 соединение с БД)

При NOMUTEX БД открыта в 1 потоке, 5 других потоков пишут в нее (1 соединение с БД) - ошибка приложение крашится.

http://www.sqlite.org/threadsafe.html

Serialized. In serialized mode, SQLite can be safely used by multiple threads with no restriction.

Multi-thread. In this mode, SQLite can be safely used by multiple threads provided that no single database connection is used simultaneously in two or more threads.

------------ Дoбавленo в 02.21:
Make(delphi)
ver(4.04 build 185)
Add(MainForm,2953706,21,105)
{
Width=348
Height=237
}
Add(Label,288061,336,175)
{
Left=17
Top=81
Width=122
Caption="NO ERRORS"
}
Add(Button,2458128,119,175)
{
Left=10
Top=47
Width=117
Caption="NOMUTEX"
link(onClick,11982242:doFor,[])
}
Add(For,11982242,217,175)
{
End=4
link(onEvent,8781949:##add,[])
}
Add(MultiElementEx,8781949,273,175)
{
Mode=1
link(onError,288061:doText,[])
}
BEGIN_SDK
Add(EditMultiEx,15934334,21,21)
{
WorkCount=#5:##add|
EventCount=#7:onError|
VarCount=#8:dbHandle|
Width=552
Height=410
Point(##add)
link(##add,14531830:doStart,[(73,27)(73,125)])
}
Add(SQLite_DB,16053219,266,112)
{
FileName="test.db"
}
Add(Thread,14531830,126,119)
{
link(onExec,16053219:doOpenN,[])
link(onSyncExec,8688802:doQuery,[(212,132)(212,167)])
}
Add(SQLite_Query,8688802,266,161)
{
SQL="insert into test values (1,'1');\r\ninsert into test values (2,'2');"
link(onError,15934334:onError,[(436,181)(436,27)])
link(dbHandle,16053219:dbHandle,[])
}
END_SDK
Add(Button,14780588,140,231)
{
Left=14
Top=118
}


А вот пример работы с MultiThread (NOMUTEX)
------------ Дoбавленo в 02.28:
Насчет примера MultiThread (NOMUTEX) немного сомневаюсь, но по моему я его верно отобразил
карма: 0

0
Ответов: 16884
Рейтинг: 1239
#14: 2015-03-08 10:43:35 ЛС | профиль | цитата
Gunnman, мы просто говорим о разных вещах.
1. SQLite - локальная БД.
2. SQLite хранит всю базу данных (включая определения, таблицы, индексы и данные) в единственном стандартном текстовом файле на том компьютере, на котором исполняется программа.
3. Перед началом исполнения транзакции записи весь файл, хранящий базу данных, блокируется стандартными средствами OC. Читать-читай, писать только по очереди.
4. Потоки, о которых ты говоришь, это потоки твоей программы. Сколько у тебя "одновременных" потоков на запись в твоей программе ?
5. Для других процессов (программ работающих на твоем компьютере с этим же файлом), режим, в котором ты получил идентификатор БД (специально не пишу "открыл файл", т.к. ты ничего не открываешь - тебе просто указывают: то, что тебе надо лежит в 1-й коробке) не имеет никакого значения.
6. Для "сетьевых" БД есть другое клиент-серверное ПО.
карма: 25
Немного терпения! Дежурный экстрасенс скоро свяжется с Вами!
0
Разработчик
Ответов: 26170
Рейтинг: 2127
#15: 2015-03-08 10:59:56 ЛС | профиль | цитата
Tad писал(а):
на том компьютере, на котором исполняется программа

Между прочим, бд очень даже неплохо читается в локальной сети с другого компа.
карма: 22

0
Сообщение
...
Прикрепленные файлы
(файлы не залиты)