web-dev-qa-db-ja.com

variable_get()は、Pressflow 6で理由なしに「デフォルト値」を使用します

現在、variable_get()に問題があります。これは、理由もなく、データベースからではなくデフォルト値を返す場合があります。ここではmemcachedを使用しています(もちろんDrupal memcachedモジュール)。

他の誰かにもこの問題がありましたか?それを修正するには?

3
Guilherme

Pressflowで使用される variable_init() のコードを見ると、次のことがわかります。

  • _MAINTENANCE_MODE_定数が定義されている場合、「variable_cache_regenerate」ロックを取得しようとします。つまり、コードは lock_acquire()TRUEを返さなくなるまで実行されません。
  • lock_acquire()TRUEを返さない場合、関数はlock_wait('variable_cache_regenerate')を呼び出してから、それ自体を再帰的に呼び出します。
  • 49回の再帰呼び出しの後、関数は_$variables_変数を空の配列に設定します。そうすることで、すべてのDrupal変数はデフォルト値に設定されます。
  • 関数内のコメントは言う:

    データベース接続が無効である場合に//無限再帰を回避するために限られた回数を試行します
    // mysqldの再起動、ネットワークの喪失などの何らかの理由.

この動作は、Drupal 6によって使用される関数にはありません。ここで、 variable_init() はロックを使用しません。

Drupal 7から同様のコードが使用されますが、わずかな違いがあります:Drupal 7はDrupalの値を読み取ります= Pressflowはこれを行わないが、データベースの変数。次のスニペットを比較してください。最初の1つはDrupal 7で使用され、2番目はPressflow 6で使用されます。

_// Cache miss. Avoid a stampede.
$name = 'variable_init';
if (!lock_acquire($name, 1)) {
  // Another request is building the variable cache.
  // Wait, then re-run this function.
  lock_wait($name);
  return variable_initialize($conf);
}
else {
  // Proceed with variable rebuild.
  $variables = array_map('unserialize', db_query('SELECT name, value FROM {variable}')->fetchAllKeyed());
  cache_set('variables', $variables, 'cache_bootstrap');
  lock_release($name);
_
_  // Wait for another request that is already doing this work.
  lock_wait('variable_cache_regenerate');

  // Run the function again. Try a limited number of times to avoid 
  // infinite recursion if the database connection is invalid for  
  // some reason, e.g., mysqld restart, loss of network, etc.
  $recursion_depth++;
  if ($recursion_depth < 50) {
    return variable_init($conf, $regenerate, $recursion_depth);
  }

  $variables = array();
_
2
kiamlaluno

うーん...追跡するのは難しいでしょう-ここの誰かがこれについて良い洞察や経験を持っているのでなければ...

私のサイトで同様の動作を見たとき、それは大きな信頼性の問題があった(ある)キャッシュルーターモジュールで(まだ壊れている)ファイルキャッシュを使用しているときでした。

それ以来、Memcache対応サイトで白いPanelsページも見ました。これは、キャッシュされたパネルページが大きすぎて、デフォルトで1Mbの「バケット」memcacheに収まらない場合に発生したと考えています。

したがって、変数テーブルが大きすぎて標準の1Mbバケットに安全に格納できない可能性があるため、バケットを大きくするか、 Variable Cleanup module を試してください。おそらく、動作の悪いモジュールをインストールした後でこれが始まりましたか?

他にも多くのことが考えられます-検討すべきいくつかのアイデアがあります:

  • 古い/障害があるDrupal Memcacheモジュール。
  • データが(mem)キャッシュに設定されたとき、またはそこから取得されたときのサイレントエラー/失敗。
  • 実行のさらに上のコードで、誤って変数に値を書き込んでいます。
  • ストロングアームまたは別のモジュールによる変数値のオーバーライド
  • 変数テーブルが正しくロードまたはキャッシュされなかったことを意味する他のいくつかのOSまたはデバッグの理由-私にはわかりません!

幸運を!

0
Jim Kirkpatrick