vews bulk operatons над 500000 нодами. Кто делал? Что делать? Сервер брать? Если да то какой?

Главные вкладки

Аватар пользователя VasyOK VasyOK 17 апреля 2012 в 13:53

Привет народ!

А кто делал с помощью модуля VBO массовые операции над 500000 нодами?

Мне нужно пересохранить 500000 нод при попытке проделать это с VBO мне пишет (Шаред Патруля):

Это внутренняя ошибка сервера
Один из наших клиентов на этом сервере вызвал перенагрузку на сервере. Мы работаем над этим. Пожалуйста обновите страницу через минуту.

Или есть другой способ пересохранить много нод?

Если сервер взять толк будет? Если да то какой?

Комментарии

Аватар пользователя VasyOK VasyOK 17 апреля 2012 в 14:13

Цель песохранения в перосохранении. Smile
Шучу. Модeль feeds не совсем корректно новые ноды на сайт заливает, поэтому вновь залитые надо пересохранять.

Аватар пользователя Chyvakoff Chyvakoff 17 апреля 2012 в 16:22

лучше узнай что конкретно в бд должно измениться-и sql запросом измени.можешь даже побить эти ноды на несколько групп.апишки друпала слишком тяжелы чтоб 500000 нод сразу апнуть.не думаю что сервак поможет.

Аватар пользователя VasyOK VasyOK 17 апреля 2012 в 16:44

Можно не сразу, могу подождать несколько часиков.

Хорошо, ставим вопрос по другому:
как sql-запросом выполнить действие "сохранить" над всеми нодами одного типа?

Аватар пользователя Shok211 Shok211 17 апреля 2012 в 17:37


<?php

# /sites/all/modules/resave.module

/**
 * Implements hook_menu().
 */

function resave_menu() {
  
/*
   *$items['blog'] = array(
   *  'title' => 'blogs',
   *  'page callback' => 'blog_page',
   *  'access arguments' => array('access content'),
   *  'type' => MENU_SUGGESTED_ITEM,
   *);
   */
  
$items['admin/config/media/resave'] = array(
    
'title' => t('Сохранить 50к материалов'),
    
'page callback' => 'drupal_get_form',
    
'page arguments' => array('resave'),
    
'access arguments' => array('administrator'),
  );

  return 

$items;
}

function 

resave()
{
  return array(array(
             
'#type' => 'submit'
           
'#value' => 'Пере сохранить материалы'
  
));
}

function 

resave_submit()

  
$type   'page'# node type
  
$result db_select('node''n')
          ->
fields('n', array('nid'))
          ->
codition('n.type'$type)
          ->
fetchAllAssoc('nid');

  foreach (

$result as $nid => $value)
     
$operations[] = array('resave_save', array($nid));

  

$batch = array(
    
'operations' => $operations
  
);
 
  
batch_set($batch);
}

function 

resave_save($nid)
{
  
$node node_load($nid);
  if (
node_save($node))
      
watchdog('resave'"Материал [$nid] сохранен");
}

?>
# /sites/all/modules/resave.info

  ; Info ;
  ; ---- ;
    name     = resave
    core     = 7.x
    package  = custom

Аватар пользователя Chyvakoff Chyvakoff 17 апреля 2012 в 17:55

"VasyOK" wrote:
Хорошо, ставим вопрос по другому:
как sql-запросом выполнить действие "сохранить" над всеми нодами одного типа?

для начала
"Chyvakoff" wrote:
лучше узнай что конкретно в бд должно измениться

потом скажу как написать запрос.

Аватар пользователя VasyOK VasyOK 17 апреля 2012 в 23:13

Chyvakoff, а как это узнать?

К примеру есть нода. Как узнать что до и после сохранения изменилось?

Shok211, почему не устраивает? Просто я вдумчивый Smile

Аватар пользователя Shok211 Shok211 17 апреля 2012 в 20:20

Чем вам мой вариант не устраивает ? Создайте файлы по пути из верхних комментариев в блоке кода и поместите в них код написанный ниже.

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 18 апреля 2012 в 0:17

Shok211, ему мало поможет ваш батч, тот запрос вывалит (если отработется вообще) массив такой величины, что шаред Васька капитулирует немедленно

VasyOK, мне интересно, откуда ты берёш такие проблемы

Аватар пользователя sg85 sg85 18 апреля 2012 в 0:43

Информация к размышлению: 500000 нод он даже на выделенном сервере будет обновлять около 2х суток, оно Вам надо?

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

Если взять сервер, то толк будет такой: можно будет создавать массивы таких размеров(в зависимости от ОЗУ на сервере), обрывов будет меньше из-за того, что Ваши соседи случайно сожрали весь траффик и т.д. и по сути на этом все)

Аватар пользователя VasyOK VasyOK 18 апреля 2012 в 0:47

Shok211, сделал модуль из 2-х файлов
resave.info - это понятно
resave.module - тут я только поменял $type = 'page'; на свой тип.

Не работает. После того как нажимаю на кнопку "Пере сохранить материалы" белый экран. Не работает даже если выбираю тип контента в котором всего одна статья.

Или еще что-то в этом коде написать?

volocuga, все таки 500 000 нод на сайт я запихал. Шаред выдержал. Батч несколько раз прерывался но после перезагузки процесс импорта продолжался с нужного места.

Хотя вопрос о сервере остается открытым.

Аватар пользователя sg85 sg85 18 апреля 2012 в 0:47

Проверьте лог ошибок, белый экран обычно идет не просто так. Про сервер уже писал, основная разница в отсутствии соседей, что то вроде жизни в частном доме, либо в квартире, в частном оно дороже, но места больше и никто перфоратором по утрам в выходные в стену не долбит)

Аватар пользователя VasyOK VasyOK 18 апреля 2012 в 1:31

Что даже с типом контента в котором одна нода белый экран, то из-за шареда?

admin/reports/dblog смотрел ничего там нет на момент появления этого белого экрана.

/*Добавлено*/
Перекинул в CSV, т.к. тот формат что был feeds не понимает. посточно - это что?

Аватар пользователя volocuga@drupal.org volocuga@drupal.org 18 апреля 2012 в 2:12

"VasyOK" wrote:
посточно - это что?

Построчно - скрипт загружает не все 500000 позиций в память, а всего одну строку, последовательно их перебирая, сверху вниз твоего CSV. Views Bulk Operations очевидно, формирует массив операций для батча примерно таким запросом к БД, как описал товарищ Shok211, да плюс джоины наверное, плюс ещё кой чего. ПХП также держит в памяти весь этот массив в памяти. Вот и считай

Аватар пользователя Chyvakoff Chyvakoff 18 апреля 2012 в 9:45

"VasyOK" wrote:
Не работает даже если выбираю тип контента в котором всего одна статья.

так значит дело не в большом количестве нод?!
"VasyOK" wrote:
нажимаю на кнопку "Пере сохранить материалы"

можете скрин этой страницы/вьюса показать..

Как узнать изменения в бд? очень просто.
Находите все записи в бд про 1 ноду.копируйте их куда то(хоть скриншоты).
пересохраняете эту ноду и опять смотрите в бд. так и поймете что меняется в базе.

Аватар пользователя Shok211 Shok211 10 ноября 2015 в 11:48

Batch может возобновляться после того как его прервали ***
Поэтому если скрипту хватает времени выбрать все 50к записей то всё должно быть ок.

<?php
# Добавляем возможность выборки по длинне
function resave()

  foreach(
node_type_get_types() as $key => $value) {
      
$options[$key] = $value->name;
  }

  

$form['type'] = array(
      
'#type' => 'select',
      
'#title'=> 'Выберите тип материала',
      
'#options' => $options,
  );

  

$form['offset'] = array(
      
'#type' => 'textfield',
      
'#title' => 'Смещение на:'
  
);
  
$form['rows'] = array(
       
'#type' => 'textfield',
       
'#title'=> 'Кол-во строк',
  );
  
  
$form['submit'] = array(
             
'#type' => 'submit'
           
'#value' => 'Пере сохранить материалы'
  
);

  return 

$form;
}

function 

resave_submit($form, &$form_state)

  
$v $form_state['values'];

  

$type   = (isset($v['type'])) ? $v['type'] : 'page'# node type

  

$result db_select('node''n');
  
$result ->fields('n', array('nid'))
          ->
condition('n.type'$type);
          

  if(

is_numeric($v['offset']) && is_numeric($v['rows']))
    
$result->range($v['offset'], $v['rows']);

  

$result $result->execute()->fetchAllAssoc('nid');

  foreach (

$result as $nid => $value)
     
$operations[] = array('resave_save', array($nid));

  

$batch = array(
    
'operations' => $operations
  
);
 
  
batch_set($batch);
}

?>

p.s Пофиксил ошибки все должно работать

Аватар пользователя VasyOK VasyOK 18 апреля 2012 в 13:21

Shok211, модуль что-то делает. Вот только что не пойму.
Нажимаю кнопку, Пишет "выполнено 1 из 1" и все. Не вижу чтобы статья пересохранилась.

Это если я выбираю тип материала в котором 1 статья.
Если я выбираю тип в котором 500 000 тогда опять пишет, что я вызвал перенагрузку на сервере.

А вот в этой строчке вместо page указать тип материала?
$type = (isset($v['type'])) ? $v['type'] : 'page'; # node type

Тогда зачем там поле выбора типа материала?

Аватар пользователя Shok211 Shok211 18 апреля 2012 в 14:11

Как вы смотрите что он пере сохранился ? Не хватает памяти на все 50к делайте порциями по 5к. Смещение на: 0, Кол-во строк 5000 => Смещение на: 5000, Кол-во строк 5000

При переходе admin/content мне выдает updated на x материалов которые я выбрал.

"VasyOK" wrote:
Тогда зачем там поле выбора типа материала?

Чтоб выбор материала проще был.

Аватар пользователя VasyOK VasyOK 18 апреля 2012 в 14:23

"Shok211" wrote:
Чтоб выбор материала проще был.

Тогда в модуле менять эту строчку
$type = (isset($v['type'])) ? $v['type'] : 'page'; # node type
если нужный тип материала не page a story ?

Мне почему-то не показывает на admin/content/node, что материал изменен.

По 5000 я умею. Пытаюсь с 500 000 Smile

Какой сервер взять, чтобы ресурсов хватило?

Аватар пользователя Shok211 Shok211 18 апреля 2012 в 14:39

Ничего изменять не надо просто выберите нужный тип материала в форме.
И уберите на время выполнения лимит по времени или сделайте его чуть больше...

Аватар пользователя VasyOK VasyOK 18 апреля 2012 в 17:16

Придется пересохранять порциями.

У меня в типе материала есть поле номер. В котором номера от 1 до 500000

Делал так: во вьюху добавил открытый фильтр. Поставил там Начинается с и можно выбрать число 111 и будут выведены все начинается с.

Вопрос: а в views фильтре можно как-то задать выборку типа от 1 до 20000 ?

Аватар пользователя VasyOK VasyOK 20 апреля 2012 в 1:24

Сделали так: поле Номер сделали числовым (до этого было текстовым) и ввели фильтр от и до.

По 20000 нод обрабатывалось без проблем. 50000 не смогли