2 место Заготовка для работы с БД MySQL в кубике C#

zhekan3

Client
Регистрация
27.12.2015
Сообщения
32
Благодарностей
4
Баллы
8
Тогда действительно странно. Работает, но без "начать сначала" это что-то новенькое ;-)
Табличка про Debug Thread Error это как я понимаю у вас в PM ?
В ZP никаких табличек не выскакивает, в логе может что-то есть?
Вообще, сам primer1.xmlz он ничего не делает и в ZP должен отрабатывать за долю секунды ... акк берется в работу, дальше там пустой кубик идет в котором я написал что вместо него там может быть все что угодно (какая-то работа с аккаунтом) и дальше работа завершается.
Может у вас в ZP все запускается как нужно и просто шаб отрабатывает за долю секунды (беря акк и ничего не делая завершается) ? И поэтому вы и видите что 0 потоков работает?) Поставьте вместо того кубика который называется "прочти меня", например паузу на 20 сек (для примера будем считать что это и есть какая-то работа с взятым аккаунтом) и проверьте еще раз....
Обновил версию до последней - работает как часы! Спасибо Вам еще раз!
 
  • Спасибо
Реакции: WebBot

alex888

Client
Регистрация
13.10.2013
Сообщения
105
Благодарностей
39
Баллы
28
голос за вас. отличная тема, спасибо за труд
 
  • Спасибо
Реакции: WebBot

aeremx

Client
Регистрация
19.09.2019
Сообщения
27
Благодарностей
8
Баллы
3
Спасибо огромное! Это то чего не хватало в ZennoPoster!
 
  • Спасибо
Реакции: WebBot

aeremx

Client
Регистрация
19.09.2019
Сообщения
27
Благодарностей
8
Баллы
3
Могу добавить, что надо не забывать добавлять одинарные кавычки, если в WHERE не цифровое значение, а строка, допустим:

db.query("UPDATE accounts SET status=0 WHERE username='"+username+"'");

Иначе будет ошибка: unknown column '[ЗНАЧЕНИЕ_ПЕРЕМЕННОЙ]' in 'where clause'
 
  • Спасибо
Реакции: MaxMan и Sardol

intagens

Client
Регистрация
28.09.2015
Сообщения
209
Благодарностей
31
Баллы
28
@WebBot подскажи, зачем закрывать сессии? что будет, если забывать их закрыть?) на сервере эти сессии будут, просто, висеть и нагружать его?
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
Могу добавить, что надо не забывать добавлять одинарные кавычки, если в WHERE не цифровое значение, а строка, допустим:

db.query("UPDATE accounts SET status=0 WHERE username='"+username+"'");

Иначе будет ошибка: unknown column '[ЗНАЧЕНИЕ_ПЕРЕМЕННОЙ]' in 'where clause'
Ну это как бы подразумевается стандартом SQL что строковые значения должны быть в кавычках.

А еще важно не забывать строковые значения экранировать т.к если в них встретиться кавычка или другие спецсимволы, то это поломает запрос.
Для этого перед тем как подставлять значение строковой перемнной в запрос, необходимо сделать:
C#:
username = db.escapeString(username);
 
  • Спасибо
Реакции: Sardol, sydoow и Lanidor

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
@WebBot подскажи, зачем закрывать сессии? что будет, если забывать их закрыть?) на сервере эти сессии будут, просто, висеть и нагружать его?
Да, закрываем что бы не висели просто так и не отжирали ресурсы машины. Они и сами закроются когда истечет таймаут, но зачем ждать когда можно закрыть самому.
 
  • Спасибо
Реакции: intagens

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
Подскажите, а с чем связана данная ошибка?
(только осваиваю работу с БД на уровне открытой сессии, не пинайте :-))
Компиляция кода Ошибка в действии "CS0246" "The type or namespace name 'DB' could not be found (are you missing a using directive or an assembly reference?)".
[Строка: 7; Cтолбец: 1]
[Строка: 7; Cтолбец: 1]
DB db = new DB(db_host, db_user, db_pswd, db_database, db_charset);
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
@zenno.xxx
Судя по всему не может найти класс DB который в заготовке находится в общем коде.
1. Вы используете заготовку с уже включенным в общий код классом?
2. MySql.Data.dll скопирован для вашей версии ZP из папки Progs в папку ExternalAssemblies ?
 

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
сейчас разберемся ;-) спасибо!

* разобрался, не перенес класс. все заработало!

проголосовал :ay:
 
Последнее редактирование:
  • Спасибо
Реакции: WebBot

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
Парни, все работает, но возник вопрос - разве MySQL работает в 1 поток?

>show status LIKE "Threads_running%"
запускал скрипт 1-5-10-15 потоков, но значение Threads_running не меняется (пробую на openserver).
такое ощущение, что запросы встают в очередь, разве не параллельно потоки должны обрабатываться?

запрос у меня простой:

var db = project.Context["db"];

// запрос к БД
string query = "SELECT titles, snippets FROM bing WHERE keywords = '" + project.Variables["skey"].Value + "' LIMIT 1";
List<string> tmp_query = db.getRow(query);
 
Последнее редактирование:
  • Спасибо
Реакции: rol

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
@zenno.xxx
Все зависит от конкретной реализации - от типов движков конкретных таблиц (myisam / innodb), использования или не использования локов и тд. В одних движках поддерживается построчная блокировка строк, в других может блочится вся таблица, где-то мы сами ставим лок и даем работать тольуо одному потоку и тд

p.s project.Variables["skey"].Value прежде чем подставлять в запрос нужно обработать с помощью db.escapeString ... что бы если там встретится кавычка или какой-нибудь спецсимвол, то запрос не поломался
 
  • Спасибо
Реакции: zenno.xxx

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
ага, это уже экранированный \' :-)

Благодарю, буду разбираться, локов таблиц не ставил. думаю они на селектах ни к чему ;-)
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
думаю они на селектах ни к чему
как раз наоборот
если мы хотим что бы каждый поток строго взял свою строку из таблицы, то нужно делать:
1) лок
2) взятие свободной строки ( например статус=0 )
3) пометка строки как занятой ( например статус=1 )
4) анлок
 
  • Спасибо
Реакции: zenno.xxx

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
:-) у меня немножечко другое направление - генерация дорвеев. практикую, так сказать, третий месяц, локальную генерацию из БД.

а тут ваша статья про сессии - удачно)) возможно даст пинок в нужном направлении.

БД innoDB (30 Гб)
keywords (Primary key) | titles | snippets
свыше миллиона записей,

примерно такие скорости генерации...

4-5к страниц (читай запросов на поток)

1 поток/дорвей = 7мин.
5 потоков/дорвеев = 21мин.
10 потоков/дорвеев = 35мин.
15 потоков/дорвеев = 45мин.
20 потоков/дорвеев = 55мин.
25 потоков/дорвеев = 75мин.

Было бы с чем сравнить, я бы сравнил - а так может разработчики/архитекторы подскажут в рамках темы, как еще можно ускорить процесс O:)
 
Последнее редактирование:

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
@zenno.xxx
Что касается структуры таблицы ... более правильно когда primary key это целочисленное автоинкрементное поле id (значение автоматически увеличивается на 1 при вставке новой записи). С таким первичным ключом будет гораздо удобнее работать - поддерживать связи между разными таблицами. А вот колонку keywords можно сделать уникальным индексом ( в вашем случае primary key так же подразумевает что значения колонки уникальны). Ну это так, чисто по структуре.

Что касается общего быстродействия генерации доров, то нужно смотреть на что вообще основное время уходит ... возможно вовсе не на работу с БД, а именно на генерацию (подготовку, обработку, замену макросов, перелинковку, запись результата в файл,, ...).
 
  • Спасибо
Реакции: zenno.xxx

Zzom

Client
Регистрация
23.05.2016
Сообщения
238
Благодарностей
66
Баллы
28
Обычно большие текстовики занимают время, поэтому с бд дорчики будут в разы быстрее постится, благодарю за статью.
 
  • Спасибо
Реакции: WebBot

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
Что касается общего быстродействия генерации доров, то нужно смотреть на что вообще основное время уходит ... возможно вовсе не на работу с БД, а именно на генерацию (подготовку, обработку, замену макросов, перелинковку, запись результата в файл,, ...).
WebBot, абсолютно верно, много времени тратилось на привязку/обработку файлов/сохранение страниц.
Ради интереса оставил только легкий код C# + обращение к БД/преобразование в макросы (в цикле), от результата "прибалдел" :ay: :az:
* есть к чему стремиться! (понятно, что это без обработки/сохранения страниц, но теперь все встало на свои места)
[09/23/2019 17:54:13][site.xxx] Генерация сайта запущена! 4825 стр.

[09/23/2019 17:54:13][site.xxx][1][Keyword_1] Спарсили тайтлы 49 шт.
[09/23/2019 17:54:13][site.xxx][1][Keyword_1] Спарсили сниппеты 50 шт.
....
[09/23/2019 17:55:04][site.xxx][4825][Keyword_4825] Спарсили тайтлы 42 шт.
[09/23/2019 17:55:04][site.xxx][4825][Keyword_4825] Спарсили сниппеты 49 шт.
;-)
Желаю Победы в 4-конкурсе шаблонов!
 
Последнее редактирование:
  • Спасибо
Реакции: WebBot

oOmp

Client
Регистрация
22.01.2018
Сообщения
198
Благодарностей
94
Баллы
28
var db = project.Context["db"]; // получаем объект из контекста string acc_id = project.Variables["acc_id"].Value; if ( acc_id != "" ){ // получаем текущее юникс-время int unixtime = (int)(DateTime.UtcNow - new DateTime(1970,1,1)).TotalSeconds; // обратно устанавливаем статус=0 (свободен) и время последнего использования устанавливаем на текущее db.query("UPDATE accounts SET status=0, use_time="+unixtime.ToString()+" WHERE id="+acc_id); } // завершаем работу с БД db.close();
Привет, не мог бы подсказать - как составить SELECT запрос в котором бы учитывалось время которое прошло с момента последнего использования, т.е допустим с момента последней записи в "use_time" прошло больше 15 минут.
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113

oOmp

Client
Регистрация
22.01.2018
Сообщения
198
Благодарностей
94
Баллы
28
Приветствую.

WHERE текущее_время_в_формате_unix-use_time >= 900

текущее_время_в_формате_unix подставляете в запрос из переменной
900 это 15*60
Спасибо, все получилось.

Если кому то понадобится:
db.getOne("SELECT channel FROM profiles WHERE UNIX_TIMESTAMP()-last_used >= 900 LIMIT 1");
 
  • Спасибо
Реакции: sydoow и WebBot

oOmp

Client
Регистрация
22.01.2018
Сообщения
198
Благодарностей
94
Баллы
28
При одновременном запуске большого количества потоков с блокировкой таблиц, через 30 секунд начинают сыпаться такие ошибки - "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."
Как я понял это из за того, что соединения отваливаются не дождавшись своей очереди. Вычитал, что за это отвечает CommandTimeout, но в файлах конфига сервера нет этого параметра.
Вроде бы CommandTimeout нужно указывать при открытии самой сессии коннекта к БД. Может кто то подсказать как это сделать?
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113
Вроде бы CommandTimeout нужно указывать при открытии самой сессии коннекта к БД. Может кто то подсказать как это сделать?
Можно обавить в connectionString значение defaultcommandtimeout=90, а можно прямо в коде его задавать

C#:
MySqlCommand command = new MySqlCommand(query, conn);
command.CommandTimeout = 90; // таймаут 90 сек
 
  • Спасибо
Реакции: zennoX, Zippy и oOmp

oOmp

Client
Регистрация
22.01.2018
Сообщения
198
Благодарностей
94
Баллы
28
При одновременном запуске большого количества потоков с блокировкой таблиц, через 30 секунд начинают сыпаться такие ошибки - "Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."
Как я понял это из за того, что соединения отваливаются не дождавшись своей очереди. Вычитал, что за это отвечает CommandTimeout, но в файлах конфига сервера нет этого параметра.
Вроде бы CommandTimeout нужно указывать при открытии самой сессии коннекта к БД. Может кто то подсказать как это сделать?
Большое спасибо, все работает.
 
  • Спасибо
Реакции: WebBot

iskrakovrov

Client
Регистрация
28.03.2015
Сообщения
532
Благодарностей
171
Баллы
43

Обращаем Ваше внимание на то, что данный пользователь заблокирован.
Не рекомендуем проводить с iskrakovrov какие-либо сделки.

А без доп библиотек реально если задачка простая в многопотоке работать заставить?

У меня такой трабл - табличка id - col1 - col2 - col3 col3 - уник. Задача просто вносить строки в таблицу - простой Insert На 200к примерно затыкается добавление - начинаются таймауты (это потоков 100) Сделано кубиком.
 

WebBot

Client
Регистрация
04.04.2015
Сообщения
1 763
Благодарностей
1 391
Баллы
113

Koqpe

Client
Регистрация
23.12.2014
Сообщения
1 100
Благодарностей
649
Баллы
113
Голосовал за Вас, но еще раз спасибо за труд, внедрил в свои проекты.
 
  • Спасибо
Реакции: WebBot и zenno.xxx

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
парни, подскажите, как работать в 30-40 потоков с БД...
Вы прописываете в OpenServer -> MySQL какие-то настройки, либо просто запускаете зенку в 30-40 потоков?
(понимаю, что от архитектуры БД/таблицы скорее зависит, но все же хотелось бы узнать, как работаете Вы)

Благодарю O:)
 

Koqpe

Client
Регистрация
23.12.2014
Сообщения
1 100
Благодарностей
649
Баллы
113
У меня БД на бегете, просто запускаю зенку в 30-40 потоков, ни разу не уперся в лимиты, шаб на пост гет запросах, в одном потоке пять обращений к таблице.
 

zenno.xxx

Client
Регистрация
05.10.2016
Сообщения
262
Благодарностей
248
Баллы
43
немного освобожусь, поищу запросы к БД, где можно вытащить кол-во обращений/потоков...
(если кто-то раньше не выложит)

* скорее у меня БД работает в 1 потоке, несмотря, что я открываю 100-200. все идет последовательно.
зависит от нагрузки. но это не точно))
 

Кто просматривает тему: (Всего: 2, Пользователи: 1, Гости: 1)